写了一篇HotSpot串行GC之full gc的分析,请大家指教
LeafInWind
2014-02-10
感谢R神一直以来慷慨的指教。
仿照R神的minor gc,写了一篇对HotSpot串行GC之full gc的分析,水平有限,只能算是浮于表面、就事论事,与R神的深度完全无法相提并论,只希望抛砖引玉,能在大家的帮助下有更深的理解。 http://leafinwind.iteye.com/blog/2012872 |
|
RednaxelaFX
2014-02-11
好!感谢楼主发帖,先鼓励一下!
LeafInWind 写道 与R神的深度完全无法相提并论,只希望抛砖引玉,能在大家的帮助下有更深的理解。
请不必妄自菲薄。你的进度在这个群组常发帖的人里面已经算非常非常好的了。肯真的深入到代码里,不畏惧细节,从中提取抽象概念出来,挺好的 =============================================== 评论一下楼主的分析。 HotSpot VM的Serial GC的full GC采用LISP2算法的mark-compact。这个算法的显著特征是分4步,包括1步mark和3步compaction: 1、标记所有活对象 2、计算所有活对象在compaction后的新地址 3、修正所有指针指向新地址 4、将对象移动到新地址 楼主帖里的那4个phase的图是自己画的不?挺形象的,画得不错 伪代码也提取得不错,基本反映了HotSpot Serial GC的做法。有些地方的非空(non-null)检查还是应该加上嗯。 后面有需要再慢慢把各种细节也捕捉到吧。 唯一不太对的地方就是这里: LeafInWind 写道 phase1对应hotspot代码的GenMarkSweep::mark_sweep_phase1方法
调用gch->gen_process_strong_roots处理根引用,使用的follow_root_closure是一个FollowRootClosure,其do_oop方法在mark当前根引用指向对象的同时,还会将该对象中的所有oop字段压入一个栈中(见MarkSweep::mark_and_push方法),然后宽度优先的mark这些间接引用的对象,直到栈为空。 是深度优先,而不是广度优先的遍历顺序喔。 只不过常见的、直观的深度优先是“左边”优先,而HotSpot的这个是“右边”优先。 如果是递归实现的深度优先搜索,那“左边”优先是很直观的;反之,使用非递归(显式栈+循环)的深度优先搜索则实现“右边”优先更方便一些。既然GC时左右哪边先都没关系,HotSpot就选了容易实现的一边。 |
|
LeafInWind
2014-02-11
R神 写道 是深度优先,而不是广度优先的遍历顺序喔。
只不过常见的、直观的深度优先是“左边”优先,而HotSpot的这个是“右边”优先。 文字上已经改过来了,伪代码应该是没有问题的。 另外添加了一点hotspot的phase2细节。 |