JVM垃圾收集(Java Garbage Collection / Java GC)

Java7

Java8

JDK1.8之后将最初的永久代取消了,由元空间取代。

堆内存调优简介

public static void main(String[] args){
	//返回 Java 虚拟机试图使用的最大内存量。
	long maxMemory = Runtime.getRuntime().maxMemory() ;
	//返回 Java 虚拟机中的内存总量。
	long totalMemory = Runtime.getRuntime().totalMemory() ;
	System.out.println("MAX_MEMORY = " + maxMemory + "(字节)、" + (maxMemory / (double)1024 / 1024) + "MB");
	System.out.println("TOTAL_MEMORY = " + totalMemory + "(字节)、" + (totalMemory / (double)1024 / 1024) + "MB");
}

发现默认的情况下分配的内存是总内存的“1 / 4”、而初始化的内存为“1 / 64”。

VM参数:-Xms1024m -Xmx1024m -XX:+PrintGCDetails

IntelliJ IDEA 的设置 

String str = "www.baidu.com" ;
while(true){
	str += str + new Random().nextInt(88888888) + new Random().nextInt(999999999) ;
}

VM参数:-Xms8m -Xmx8m -XX:+PrintGCDetails

 

官网访问地址:

public static async Task<JObject> GetJsonAsync(Uri uri)
{
using (var client = new HttpClient(www.yongshiyule178.com))
{
var jsonString = await client.GetStringAsync(uri);
return JObject.Parse(jsonString);
}
}

// 顶层调用方法
public void Button1_Click(...)
{
var jsonTask = GetJsonAsync(www.huarenyl.cn...);
textBox1.Text = jsonTask.Result;
}
复制代码
  ASP.NET例子:API Action发起远程HTTP请求,等待请求的json结果,并解析json字符串,以下代码也会引发deadlock
复制代码
public static async Task<JObject> GetJsonAsync(Uri uri)
{
using (var client = new HttpClient())
{
var jsonString = await client.GetStringAsync(uri);
return JObject.Parse(jsonString);
}
}
// My "top-level"www.taoyyunsheng.com method.
public class MyController : ApiController
{
public string Get()
{
var jsonTask = GetJsonAsync(www.honglanggjpt.cn...);
return jsonTask.Result.ToString();
}
}
复制代码

   解决以上deadlock需利用以上第②③条编程原则:
不要混合使用异步、同步代码,始终使用async/await语法糖编写异步代码

在等待的异步任务内应用ConfigureAwait(false)方法 (:不再尝试从捕获的同步上下文执行异步编程的后续代码)

   第②③条原则与我们今天的主角SynchronizationContext 密切相关,大多数时候SynchronizationContext 是在异步编程后面默默工作的, 但是了解这个对象对于理解Task、await/sync 工作原理大有裨益。本文会解释
为什么要有SynchronizationContext 对象

阐述await关键字与SynchronizationContext对象交互原理

以上代码为什么会有deadlock, 另外ASP.NET Core为什么不会发生以上死锁

1. The Need for SynchronizationContext
  先看下MSDN中关于SynchronizationContext的定义:
提供在各种同步模型中传播同步上下文的基本功能。此类实现的同步模型的目的是允许公共语言运行库的内部异步/同步操作使用不同的同步模型正常运行。
  上面的定义给我的印象是:在线程切换过程中保存前置线程执行的上下文环境。

  我们大家都知道:Windows Form和WPF都基于类似的原则: 不允许在非UI线程上操作 UI元素

  
  这个时候我们可以捕获当前执行环境SynchronizationContext,利用这个对象切换回原UI线程。

复制代码
public static void DoWork()
{
//On UI thread
var sc = SynchronizationContext.Current;

ThreadPool.QueueUserWorkItem( www.365soke.com delegate
{
// do work on ThreadPool
sc.Post(delegate
{
// do work on the original context (UI)
}, null);
});
}
复制代码
SynchronizationContext表示代码正在运行的当前环境,每个线程都有自己的SynchronizationContext,通过SynchronizationContext.Current可获取当前线程的同步上下文。利用该对象,可在线程池线程B执行完成后,尝试切换到原调用线程A执行特定代码。

2. await/async语法糖与SynchronizationContext 的关系?
  以上ThreadPool.QueueUserWorkItem 涉及线程底层,微软提出Task线程包装类和 await/async 简化了异步编程的方式:

  
  ① 调用异步方法GetStringAsync时,.NET框架为我们创建了异步任务T;
  ② 应用await时,框架捕获当前环境, 存储在SynchronizationContext 对象并附加于以上Task;

  ③ 同时,控制权返回到原上层调用函数,返回一个未完成的Task<int>对象,这个时候需要关注上层调用函数使用 await异步等待还是使用Result/Wait()方式同步等待

  ④ 异步任务T执行完成,await之后的代码将会成为continuation block, 默认情况下利用捕获的SynchronizationContext 对象执行该continuation block 代码。

    内部实际是将continuation block代码放入 SynchronizationContext 的Post方法。

    不同的.NET框架因各自独特的需求 有不同的 Post实现(Post是一个虚方法):

- 默认的SynchronizationContext.Post实现是将 委托通过QueueUserWorkItem传递给 ThreadPool。

- Windows Form有WindowsFormSynchronizationContext, Post方法将委托传递给 Control.BeginInvoke

- WPF 有DispatcherSynchronizationContext , Post方法将委托传递给 Dispatcher.BeginInvoke

3.引言代码为什么发生deadlock, 而ASP.NET Core为什么不会发生类似deadlock?
仔细观察引言代码,控制返回到 上层调用函数时, 该调用函数使用Result属性去等待任务结果,Result/Wait()等同步方式会导致调用线程挂起等待任务完成。而在异步方法内部,await触发的异步任务执行完成后,会尝试利用捕获的同步上下文执行剩余代码,而该同步上下文中的线程正同步等待整个异步任务完成,形成死锁。

正因为如此,我们提出:

  - 在原调用函数始终 使用 await方法,这样该线程是异步等待 任务完成。

  - 在异步任务内部应用ConfigureAwait(false)方法:

MSDN ConfigureAwait(www.dfgjpt.com): true to attempt www.gouyiflb.cn/ to marshal the continuation back to the original context captured; otherwise, false
  另外注意:ASP.NET Core不存在SynchronizationContext , 故不会发生类似的死锁。

总结:
  虽然await/async 语法糖让我们在编写.NET 异步程序时得心应手、随心所欲,但是不要忘记了SynchronizationContext 在其中转承起合的作用。

利用能够保存当前执行代码的上下文特性,SynchronizationContext在线程切换后帮我们有能力执行各种骚操作。

-XX:+HeapDumpOnOutOfMemoryError OOM时导出堆到文件。

-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError

JVM垃圾收集(Java Garbage Collection / Java GC)的更多相关文章

  1. JVM学习二:垃圾收集(Garbage Collection,GC)机制

    JVM的GC分为两个主要部分,第一部分是判断对象是否已死(堆内存的垃圾回收占主要部分,方法区(metaspace)的内存回收在最新的官方文档中未给出详细解释,暂时不做讨论范围),第二部分是对内存区进行 ...

  2. [翻译]Java垃圾收集精粹(Java Garbage Collection Distilled)

    source URL: http://www.infoq.com/articles/Java_Garbage_Collection_Distilled Name: Java Garbage Colle ...

  3. Java Garbage Collection Basics--转载

    原文地址:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html Overview Purpose ...

  4. 四.GC —三分钟认识JAVA回收机制(Java Garbage Collection)

    这里以jdk1.8做讲解.Jdk1.8的分代去掉了永久代,只分为新生代(有的也译为年轻代)和年老代. 名词解释: 系统吞吐量:用于处理应用程序处理事务的线程数与用于GC的线程数的比. pause ti ...

  5. Java Garbage Collection基础详解------Java 垃圾回收机制技术详解

    最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面试官问的时候也不存在问题,直到那天该公司一个做搜索的面试官问了我GC的问题,具体就是:老年代使用的是哪中垃圾 ...

  6. Java Garbage Collection

    在C/C++中,需要自己负责object的creation 和 destruction. 如果忘记了destruction, 就容易出现OutOfMemoryErrors. Java中会有GC直接处理 ...

  7. Java Garbage Collection/垃圾收集 策略查看

    Java 的垃圾收集有各种各样的策略,默认的策略也会经常的改变. --比如到底是 serial , parallel, CMS; 具体到 Minor 怎么样,Old 又怎么样? 命令 java -XX ...

  8. Java虚拟机(Java Virtual Machine)

    JVM(Java Virtual Machine),Java虚机机,是JDK最底层的东西.只要能将源代码编译成字节码(.class)文件,就可以由JVM在不同平台上解释成机器指令来执行.所以,Java ...

  9. 深挖Jvm垃圾收集

    垃圾收集(Garbage Collection,GC),它的任务是解决以下 3 件问题: 哪些内存需要回收? 什么时候回收? 如何回收? 其中第一个问题很好回答,在 Java 中,GC 主要发生在 J ...

随机推荐

  1. 用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。

    https://code.google.com/p/dotnet-big-decimal/ 这是个BigDecimal类的开源项目,支持Operators +, - and *. 俺给改了改,加上了除 ...

  2. css行内省略号、垂直居中

    应用场景分析: 一.当你的文字限定行数,超出部分的文字用省略号显示. (有两个使用场景:1.单行 2.多行) // 单行 overflow: hidden; text-overflow:ellipsi ...

  3. React Native之FlatList的介绍与使用实例

    React Native之FlatList的介绍与使用实例 功能简介 FlatList高性能的简单列表组件,支持下面这些常用的功能: 完全跨平台. 支持水平布局模式. 行组件显示或隐藏时可配置回调事件 ...

  4. MySQL — 优化之explain执行计划详解(转)

    EXPLAIN简介 EXPLAIN 命令是查看查询优化器如何决定执行查询的主要方法,使用EXPLAIN,只需要在查询中的SELECT关键字之前增加EXPLAIN这个词即可,MYSQL会在查询上设置一个 ...

  5. [转帖]一个ip对应多个域名多个ssl证书配置-Nginx实现多域名证书HTTPS

    一个ip对应多个域名多个ssl证书配置-Nginx实现多域名证书HTTPS https://home.cnblogs.com/u/beyang/ 一台服务器,两个域名 首先购买https,获取到CA证 ...

  6. [转帖]Linux:cut命令详解

    Linux:cut命令详解 https://www.cnblogs.com/Spiro-K/p/6361646.html cut -f cut -f -d cut -c1- 这三个命令好像最常见, 记 ...

  7. js的日期操作:String转date日期格式、求日期差

    一.在js中String类型转成date格式 var date = new Date("2018-9-21 14:58:43");//就是这么简单 二.date转String类型就 ...

  8. hive条件函数

    case相当于if,when相当于=:then是条件满足的结论.否则实行else后语句,一end结束

  9. Antd & ice

    Antd & ice Angular https://github.com/NG-ZORRO/ng-zorro-antd https://ng.ant.design/docs/introduc ...

  10. css3实现背景渐变

    #grad { background: -webkit-linear-gradient(left,rgba(255,0,0,0),rgba(255,0,0,1)); /* Safari 5.1 - 6 ...