也谈JVM垃圾回收

来源:互联网 发布:windows管理模板 编辑:程序博客网 时间:2024/05/16 15:01

垃圾回收算法整理

1.标记-清除
2.标记-整理
3.标记-复制

上面三种回收算法思想很多资料上都有说明,这里就不细说了,有很多资料上会把增量回收和分代回收归类为回收算法,我个人并不这么认为,因为增量回收和分代回收只是为了更好的利用上面三种回收算法,它们两个并不是直接回收垃圾的算法。

先有鸡还是先有蛋?

很多资料上来就说java堆分为新生代和老年代,新生代又细分为1个eden区和2个survive区,其实这个说法是不准确的。
JVM的堆只是向操作系统申请的一个内存区并没有进行任何划分,而具体的划分都是有垃圾收集器去做的,而垃圾收集器会
基于上面提到的回收算法思想结合实际请求进行回收。

所以不是因为java堆划分为多个区而使用多种回收算法合作,而是因为采用了相应的回收算法才决定内存区的划分方式。下面具体说一下:
1.分新生代和老年代
为什么要分代?在一群对象中处理少部分对象永远比处理大部分对象的成本要小,新生代默认为生存的对象少,采用标记-复制,
老年代默认的死亡对象少使用标记-清除
2.新生代再划分1个eden和2个survive区,默认比例为8:1
首先说一下比例问题,由于大部分对象是朝生夕死的,幸存下来的是少数,所以eden区比survive区大,又因为幸存下来的对象是少数,
所以采用复制算法的成本较低
总说一句就是java堆本身只是一块内存区并没有任何划分,划分是由垃圾收集器完成的,而我们平常见到的新生代,老年代的划分方式都是
在现有算法基础上的划分,当使用G1收集器的时候虽然仍然保留了新生代老年代的概念,但堆内存就不再是这种划分方式了。

简单写一下CMS吧

1.初始标记
现在判断对象存活的方式是可达性判断,初始标记从GC ROOT出发只寻找与ROOT节点直接关联的节点,即只向下查找一级这里是stop the world
2.并发标记
这个时候用户线程可以执行,回收线程是基于初始标记结果继续遍历所有对象,判断可达性。
3.最终标记
这个过程是stop the world的,目的是对第二步中用户线程产生对象的引用进行可达性分心。
4.筛选回收
这个时候与用户线程并发执行,进行清理工作。

0 0
原创粉丝点击