对于这块知识,看深入理解Java虚拟机和相关博客时总觉得迷迷糊糊的,对于什么时候触发哪种gc,哪种垃圾回收器对应哪种gc机制还是一知半解,下面总梳理下自己的理解,如果有误,欢迎指正:
1. minor gc
这点没有什么好说的, 就是yong gen空间不足时触发minor gc,可使用的垃圾回收器有 Serial , ParNew, Parallel Scavenge,G1等收集器
2.major gc/ old gc
major gc一般指的就是对于old gen的垃圾回收,最困惑的地方就是在这里:
只有CMS垃圾回收器会对老年代进行垃圾回收,其余垃圾回收都是在minor gc时发现新生代将要晋升到老年代的对象在老年代中放不下,就会触发full gc,注意这里是full gc,而不是Old gc。
如果老年代的垃圾回收器采用了CMS垃圾回收器,则在老年代内存不足时,使用CMS对老年代进行垃圾回收,这时候对老年代采用的垃圾回收算法是标记清理算法,其余的垃圾回收算法都是在minor gc时发现空间不足触发full gc 时才对老年代进行垃圾回收的,CMS会在老年代内存达到阈值主动对老年代进行垃圾回收。CMS垃圾回收不会默认在old gc前进行一次minor gc,最好在cms进行old gc前进行一次minor gc,这样效率会大大提高。可以通过参数配置,而除了CMS的并发收集外,其它能收集 old gen的GC都会哦那个是收集整个GC堆,包括young gen,所以 不需要事先触发一次full GC
3.mixed gc
mixed gc是只有G1垃圾收集器才会触发的, mixed gc是指新生代gc+部分老年代gc,注意是部分,不是对整个老年代进行gc。当老年代的内存使用率达到某个阈值就会触发混合GC
4.full gc
full gc是指对全堆进行垃圾回收,包括新生代,老年代,如果方法区由永久代实现,则包括永久代,方法区由元空间实现不包括元空间,很多文章说full gc也对元空间进行回收,我认为是不对的。full gc前默认对年轻代进行一次Minor GC。
HotSpot的full GC实现中,默认young gen里所有活的对象都要晋升到old gen,实在晋升不了才会留在young gen。假如做full GC的时候,old gen里的对象几乎没有死掉的,而young gen又要晋升活对象上来,那么full GC结束后old gen的使用量自然就上升了。(这段引自R神的回答)
Full GC触发条件:
1>调用System.gc时,系统建议执行Full GC,但是不必然执行;
2>老年代空间不足;
3>方法区空间不足;
4>通过Minor GC后进入老年代的平均大小大于老年代的可用内存;
5>由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。(分配担保机制)
5.MetaSpace gc
当元空间的内存不足时,会触发MetaSpace gc,元空间大小默认好像是21M,因为元空间的垃圾回收需要判断某一个类是否还有对应的实例对象,而实例对象在堆中,所以这时候会触发full gc去扫描整个堆。
如何判断一个类是无用的类,元空间中放的就是类的相关信息,用于元空间 gc 1>该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。 2>加载该类的 ClassLoader 已经被回收。 3>该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法6.几种常见垃圾回收器的full gc
Serial ParNew Parallel CMS这四个垃圾回收器 都会在Minor gc时检查到需要full gc,或者往old gc中放不下时触发 full gc,而CMS比前三个垃圾回收器多的是,它在老年代空间达到阈值时进行,老年代的垃圾回收,并且会内存碎片过多时会退化成serial old进行一次gc(这次gc属于full gc? 存在疑问) G1垃圾回收器分为 minor gc,mixed gc 和full gc三个阶段,与其他新生代收集器类似,对象优先在eden region分配,如果eden region内存不足就会触发新生代的GC,把存活的对象安置在survivor region,或者晋升到old region,当越来越多的对象晋升到了old region,当老年代的内存使用率达到某个阈值就会触发混合GC,混合GC会回收新生代和部分老年代内存,注意是部分老年代而不是全部老年代。如果对象内存分配速度过快,混合GC还未回收完成,导致老年代被填满,就会触发一次full gc。
目前还存在疑问的地方:
1>full gc使用的是什么算法,在新生代和老年代中根据不同的垃圾回收器选择对应的算法吗?
2>CMS 退化成serial old进行一次gc,这次gc属于full gc? 存在疑问
3>G1垃圾回收器full gc 也使用的是serial old吗?
以上疑问以后回来补坑!!!