GC回收机制

一、GC要做的事

  1、哪些内存需要回收,2、什么时候回收,3、怎么回收

二、如何确定内存垃圾

  1、引用计数法:通过判断对象的引用数量来决定对象是否可以被回收,任何引用计数为0的对象实例可以被当做垃圾收集

   优:执行效率高,程序执行受影响小

   缺:无法检测出循环引用的情况,导致内存泄漏。eg:父对子有一个引用,子对父也有一个引用,所以两个对象引用用不为0

  2、可达性分析:判断对象的引用链是否可达来决定对象是否可以被回收,通过GC Root到各对象是否可达来判断

   可作为GC Root的对象:虚拟机栈中引用的对象(栈帧中的本地变量表),方法区中的常量引用的对象,方法区中的类静态属性引用的对象,本地方法栈中JNI(Native)的引用对象,活跃线程的引用对象。

三、垃圾回收算法

  1、标记-清除算法:可达性分析

  标记:从根集合进行扫描,对存活的对象进行标记,清除:对堆内存从头到尾进行线性遍历,回收不可达对象内存

   2、复制算法:(新生代)

  分为对象面和空闲面,对象在对象面上创建,存活的对象被从对象面复制到空闲面,将对象面所有对象内存清除。对象存活率低(新生代)

  解决了碎片化问题,新生代中,对象存活率低,所以要复制的对象很少,此方法顺序分配内存,简单高效。存活率较高时就会力不从心

  3、标记-整理算法:(老年代)

  标记:从根集合进行扫描,对存活的对象进行标记,清除:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。在标记-清除算法的基础上,添加了移动的功能

  4、分代手机算法:

  按照对象生命周期的不同划分区域以采用不同的垃圾回收算法,提高jvm垃圾回收效率

  GC 的分类:

    (1/3堆内存空间)Minor GC:所有新生成的对象一般都在新生代

      Eden(伊甸园),  80%,两个Survivor区(from,to),10%

        Eden中存储对象,当达到阈值后(Minor次数),会向任意一个Survivor区中存储Eden中当前还存活的对象,清除Eden中所有对象,且年龄+1,此时当前区就成了from区,当下一次Eden又达到阈值,且当前Survivor区也达到了阈值,此时会向另外一个Survivor区存储,年龄+1,另外一Survivor区就会变成from区。

  对象如何晋升到老年代:

    1、经历一定Minor次数(默认15)依然存活的对象,2、Survivor区中存放不下的对象,3、新生成的大对象。

    (2/3堆内存空间)Full  GC:存放生命周期较长的对象

      标记-清除算法,标记-整理算法

      Full GC  和Major GC,Full GC 比Minor GC 回收效率慢,但执行频率低。

    触发Full GC 的条件

      老年代空间不足,永久代空间不足

四、垃圾收集器

  

 CMS和Parallel Scavenge收集器不能共存,因为,Parallel Scavenge和G1使用的都是类似于框架,不能与CMS更好的共存

新生代垃圾收集器:

   1、Serial收集器(-XX:+UseSerialGC,复制算法)

    单线程收集,进行垃圾收集时,必须暂停所有工作线程

    简单高效,Client模式下的年轻代收集器

   2、ParNew收集器(-XX:+UseParNewGC,复制算法)

    多线程收集,其余的行为、特点和Serial收集器一样

    单核执行效率不如Serial(由于线程切换需要开销),多核下执行才有优势

   3、Parallel  Scavenge收集器(-XX:+UseParallelGC,复制算法)

      吞吐量= 运行代码时间/(运行代码时间+垃圾回收处理时间)

    比起之前两个关注用户线程停顿时间,更关注系统的吞吐量

    多线程下执行才有优势,Server模式下的年轻代收集器

老年代垃圾收集器:

   1、Serial  Old收集器(-XX:+UseSerialOlaGC,标记-整理算法)     

    单线程收集,进行垃圾收集时,必须暂停所有工作线程

    简单高效,Client模式下的年轻代收集器

    2、Parallel  Old收集器(-XX:+UseParallelOldGC,标记-整理算法)

     多线程,吞吐量优先

   3、CMS收集器(-XX:+UseConcMarkSweepGC,标记-清除算法)  

G1和CMS的回收机制

G1同时回收老年代和年轻代,而CMS只能回收老年代,需要配合一个年轻代收集器。另外G1的分代更多是逻辑上的概念,G1将内存分成多个等大小的region,Eden/ Survivor/Old分别是一部分region的逻辑集合,物理上内存地址并不连续。

原文地址:https://www.cnblogs.com/guanyuehao0107/p/12045317.html