java gc --- 关键词解释
分代gc
java的堆内存主要分为young generation与old generation,这两块分开回收。这就是所谓的分代gc
其中young generation又分为一个eden space与两个survivor space(From与To)。默认情况下,eden space占young generation的80%,两个survivor space各占10%。
young gc:新对象一般在eden space中分配,如果eden space满了,就进行一次。eden space + From 中的所有存活对象会被复制到To里去(这是因为大部分的新分配对象都会迅速死亡,每个survivor space虽然只占young generation的10%,但是一般情况下足够存放young gc中的存活元素)。每次young gc之后,From与To交换。
每个Object的对象头里都有字段用于记录这个对象经历了多少次young gc。如果一个对象熬过了一定次数(可以通过-XX:MaxTenuringThreshold配置,默认为15次)的Young gc而不死,那么可以晋升到old generation。
如果新对象的体积过大(可以通过-XX:PretenureSizeThreshold配置,但是该设置只对Serial和ParNew收集器生效),那么它会被直接分配到old generation
full gc:如果old generation也满了,就会触发full gc。full gc会对整个堆空间做gc。具体的操作是从gc root(下文介绍)出发,遍历所有可达对象,然后回收所有不可达对象。正常情况下会回收大量的内存,如果full gc后还是无法获得足够分配对象的内存,就会抛出OOM错误。
一般来说young gc的耗时较少(数十或者数百毫秒级别),full gc耗时较长(一般在秒级别,如果堆内存很大,甚至可以产生分钟级别的停顿)
gc root
gc的起点,一组可以保证绝对存活的对象,例如:
Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。我们需要注意的一点就是,通过用户自定义的类加载器加载的类,除非相应的java.lang.Class实例以其它的某种(或多种)方式成为roots,否则它们并不是roots,.
Thread - 活着的线程
Stack Local - Java方法的local变量或参数
JNI Local - JNI方法的local变量或参数
JNI Global - 全局JNI引用
Monitor Used - 用于同步的监控对象
Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此就只有留给分析分员去确定哪些是属于"JVM持有"的了。
remember set/card table/write barrier
重新考虑上文提到的young gc,我们怎样才能知道young gen中的哪些对象是可达的?
最朴素的思想当然是从gc root出发,对整个heap中的对象进行可达性分析。这毫无疑问可以解决问题,但是如果这样做,young gc和full gc又有什么区别呢?
所以我们需要额外的机制来记录,old gen中的哪些对象引用了young gen中的对象。也可以理解为扩充了young gc中gc root的范围。
Remembered Set是在实现部分垃圾收集(partial GC)时用于记录从非收集部分指向收集部分的指针的集合的抽象数据结构。
card table是remember set的一种实现,card table实际上是一个byte数组,card table中的每个byte(也就是所谓的card)都对应了old gen中的一小块内存(chunk,默认是512byte)。如果card table中的某个card被标记为dirty,那么这个card对应的chunk中可能存在指向young gen的对象。在young gc时,就只需要扫描gc root + old gen中的dirty chunk中的对象即可。
card table的维护是由write barrier来完成的。任何对old gen中对象的修改,都会导致这个对象所在的chunk对应的card被标记为dirty。
card table的维护会带来一定的开销,但是根据统计分析,它确实可以极大的减少young gc的开销,所以还是值得的。
stw
stop the world,顾名思义,jvm中的所有工作线程都会暂停。此时整个java进程处于无响应状态。
young gc与full gc都会引起stw,只是时间长短的区别
promotion guarantee check
本节的讨论基于CMS算法
每次Minor GC执行完以后,虚拟机会检查之前晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则发起一次Full/Major GC,如果小于,则查看HandlePromotionFailure值是否允许担保失败,如果允许,那只会进行一次Minor GC。如果不允许失败,那么也要改为进行一次Full/Major GC
如果young gc时,To的空间不足以存放From + Eden中的存活对象,那么这些对象会被直接移动到old gen中(即使它们的年龄还不足以提升到old gen,这个情况叫做premature promotion,中文大概叫“过早提升”,它会导致full gc频率提高,jvm虽然尽力优化,但还是无法避免)。如果此时old gen的空间也不足,就会引发Promtion failed。Promtion failed会引发full gc。
concurrent mode failure
Concurrent Mode Failure
The CMS collector uses one or more garbage collector threads that run simultaneously with the application threads with the goal of completing the collection of the tenured generation before it becomes full. As described previously, in normal operation, the CMS collector does most of its tracing and sweeping work with the application threads still running, so only brief pauses are seen by the application threads. However, if the CMS collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfied with the available free space blocks in the tenured generation, then the application is paused and the collection is completed with all the application threads stopped. The inability to complete a collection concurrently is referred to as concurrent mode failure and indicates the need to adjust the CMS collector parameters. If a concurrent collection is interrupted by an explicit garbage collection (System.gc()) or for a garbage collection needed to provide information for diagnostic tools, then a concurrent mode interruption is reported.
1. 如果old gen在被用完前不能完成对无引用对象的回收。
2. 如果old gen中的剩余空间不能满足应用的内存分配需求。
上面这两个场景会引发Concurrent Mode Failure,此时old gen的收集器会从CMS切换到Serial Old,这会引起一次有非常长的stw的full gc
参考资料
http://hllvm.group.iteye.com/group/topic/21468#post-272070 RednaxelaFX对card table的说明
http://blog-archive.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots.html card table + 分代gc
https://blogs.msdn.microsoft.com/abhinaba/2009/03/02/back-to-basics-generational-garbage-collection/ 微软对card table的说明
http://dept.cs.williams.edu/~freund/cs434/hotspot-gc.pdf card table + 分代gc
https://www.yourkit.com/docs/java/help/gc_roots.jsp gc root都有什么?
http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html oracle官方的gc调优文档
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html oracle官方对cms的说明
java gc --- 关键词解释的更多相关文章
- 详解Java GC的工作原理+Minor GC、FullGC
详解Java GC的工作原理+Minor GC.FullGC 引用地址:http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html J ...
- 成为Java GC专家(3)—如何优化Java垃圾回收机制
为什么需要优化GC 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但前提是所运行的基于Java的系统,包含了如下参数或 ...
- Java GC 日志详解(转)
Java GC日志可以通过 +PrintGCDetails开启 以ParallelGC为例 YoungGC日志解释如下(图片源地址:这里) : FullGC(图片源地址:这里): http://blo ...
- Java GC - 监控回收行为与日志分析
1. 简介 在上一篇介绍<Java GC - 垃圾回收机制>, 本文将介绍如何监控 Javc GC 行为,同时涉及一些GUI工具的使用(虽然有些已经很老并不再更新),监控GC在于判断JVM ...
- Java GC 日志详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt105 java GC日志可以通过 +PrintGCDetails开启 以Pa ...
- jvm系列(十):如何优化Java GC「译」
本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...
- Java GC性能优化实战
GC优化是必要的吗? 或者更准确地说,GC优化对Java基础服务来说是必要的吗?答案是否定的,事实上GC优化对Java基础服务来说在有些场合是可以省去的,但前提是这些正在运行的Java系统,必须包含以 ...
- JVM垃圾收集(Java Garbage Collection / Java GC)
JVM垃圾收集(Java Garbage Collection / Java GC) Java7 Java8 JDK1.8之后将最初的永久代取消了,由元空间取代. 堆内存调优简介 public sta ...
- jvm系列(七):如何优化Java GC「译」
本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...
随机推荐
- 机顶盒demux的工作原理
在机顶盒中demux部分相对来说是比较复杂的部分,对于机顶盒软件开发的新手来说通常在这里会遇到一些困难,今天特意研究了一下驱动层代码,有一点自己的理解,因此写下来记录一下学习过程. 机顶盒中数据是如何 ...
- Word 2013发布博客测试
Hello world ! I am from word2013! 测试修改 这里添加一行文字. 参考 1在 Word 中建立博客的相关帮助 2使用Word2013发布随笔到博客园 PS: 参考2 ...
- winform中使用webBrowser时如何与JS交互
最近写一个GEPlugin项目,要用到geWebBrowser与JS进行交互. 这个geWebBrowser的事件 private void geWebBrowser1_DocumentComplet ...
- Linux下Oracle JDK替换Open JDK
Oracle的产品需要Oracle JDK,但是Linux发行版附带的都是开源的Open JDK,这里给出的方法是在不删除原有Open JDK的情况下,安装Oracle JDK 环境 系统:CentO ...
- OpenCV学习笔记(七) 图像金字塔 阈值 边界
转自: OpenCV 教程 使用 图像金字塔 进行缩放 图像金字塔是视觉运用中广泛采用的一项技术.一个图像金字塔是一系列图像的集合 - 所有图像来源于同一张原始图像 - 通过梯次向下采样获得,直到达到 ...
- sqoop安装和使用
下载版本:sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz 官网:http://mirror.bit.edu.cn/apache/sqoop/1.4.6/ jdbc ...
- xgboost原理总结和代码展示
关于xgboost的学习推荐两篇博客,每篇看2遍,我都能看懂,你肯定没问题 两篇方法互通,知识点互补!记录下来,方便以后查看 第一篇:作者:milter链接:https://www.jianshu.c ...
- loj2059 「TJOI / HEOI2016」字符串
字符串好难啊不会啊 #include <iostream> #include <cstdio> using namespace std; int n, m, rnk[10000 ...
- Hive官方文档
Hive官方文档 内容列表 Cloudera制作的Hive介绍视频 安装与配置 系统需求 安装Hive发行版 从Hive源码编译 运行Hive 配置管理概览 运行时配置 Hive, Map-R ...
- 【bzoj4589】Hard Nim FWT
题目描述 Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: 1. Claris和NanoApe两个人轮流拿石子,Claris先拿. 2. 每次只能从一堆中取若干个,可将一堆全取走, ...