For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
垃圾回收机制是Java程序员在学习与工作中都需要熟练掌握的一个编程开发技术,而本文我们就通过案例分析来简单了解一下,Java虚拟机三色标记算法概念与应用分析。
1、三色标记算法
三色标记算法指的是将所有对象分为白色、黑色和灰色三种类型。黑色表示从GCRoots开始,已扫描过它全部引用的对象,灰色指的是扫描过对象本身,还没完全扫描过它全部引用的对象,白色指的是还没扫描过的对象。
2、多标与漏标问题
多标问题指的是原本应该回收的对象,被多余地标记为黑色存活对象,从而导致该垃圾对象没有被回收。多标问题会导致内存产生浮动垃圾,但好在其可以再下次GC的时候被回收,因此问题还不算很严重。
漏标问题指的是原本应该被标记为存活的对象,被遗漏标记为黑色,从而导致该垃圾对象被错误回收。
3、漏标解决方案
正如前面所说,三色标记算法会造成漏标和多标问题。但多标问题相对不是那么严重,而漏标问题才是严重的。我们经过分析可以知道,漏标问题要发生需要满足如下两个充要条件:
有至少一个黑色对象在自己被标记之后指向了这个白色对象
所有的灰色对象在自己引用扫描完成之前删除了对白色对象的引用
只有当上面两个条件都满足,三色标记算法才会发生漏标的问题。换言之,如果我们破坏任何一个条件,这个白色对象就不会被漏标。这其实就产生了两种方式,分别是:增量更新、原始快照。CMS回收器使用的增量更新方案,G1采用的是原始快照方案。
4、CMS解决方案
CMS回收器采用的是增量更新方案,即破坏一个条件:「有至少一个黑色对象在自己被标记之后指向了这个白色对象」。
既然有黑色对象在自己标记后,又重新指向了白色对象。那么我就把这个黑色对象的引用记录下来,在后续「重新标记」阶段再以这个黑色对象为根,对其引用进行重新扫描。通过这种方式,被黑色对象引用的白色对象就会变成灰色,从而变为存活状态。
这种方式有个缺点,就是会重新扫描新增的这部分黑色对象,会浪费多一些时间。但是这段时间相对于并发标记整个链路的扫描,还是小巫见大巫,毕竟真正发生引用变化的黑色对象是比较少的。
5、G1解决方案
G1回收器采用的是原始快照的方案,即破坏二个条件:「所有的灰色对象在自己引用扫描完成之前删除了对白色对象的引用」。
既然灰色对象在扫描完成前删除了对白色对象的引用,那么我是否能在灰色对象取消引用之前,先将灰色对象引用的白色对象记录下来。随后在「重新标记」阶段再以白色对象为根,对它的引用进行扫描,从而避免了漏标的问题。通过这种方式,原本漏标的对象就会被重新扫描变成灰色,从而变为存活状态。
这种方式有个缺点,就是会产生浮动垃圾。因为当用户线程取消引用的时候,有可能是真的取消引用,对应的对象是真的要回收掉的。这时候我们通过这种方式,就会把本该回收的对象又复活了,从而导致出现浮动垃圾。但相对于本该存活的对象被回收,这个代价还是可以接受的,毕竟在下次GC的时候就可以回收了。
对于CMS和G1这两种处理方案哪种更好,很多资料说的是G1这种解决方案更好。原因是其觉得G1这种方式产生了一些浮动垃圾,但节省了一些时间。但我对比了一下发现:CMS和G1都需要重新对某些元素进行引用链扫描。从这点看来,好像差别不大。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。