开篇
临时接到一个面试邀约,慌的要死啊,自从上次拿了京东Offer后,就没有准备过面试了,这个把自己刚刚看的JVM的之前记忆有些模糊的地方,做一点记录。
正文- 垃圾回收的几个典型算法【经典的图】
- 标记清理:CMS的Major GC默认
- 标记复制:只会有一部分被使用,ParNew
- 标记整理:CMS的FullGC
- 关于几个GC的说法
- Minor GC 年轻代的GC
- Major GC 是老年代的GC
- Full GC是整个Java堆的GC
- Java的所有线程到达“安全点”才会进行GC,其中存在于2处:
- 分配内存的地方,比如
new
- 预期耗时较长的行为前,比如
for while
循环
- 对于上述情况,当某个线程阻塞或者等待的时候,无法到达安全点,此时线程要预先标记自己是安全区域。同时离开的时候要判定当前的GC ROOT判定是否结束。
- CMS算法的特点:
- 并发:垃圾回收线程同工作线程同时执行的
- 所以可能出现垃圾回收期间,工作线程还在产生新的垃圾,这类垃圾叫做“浮动垃圾”,下一次GC清理。
- CMS算法是默认情况 标记清理,默认设置下FullGC的时候标记整理
- ParNew是默认情况下CMS的搭配年轻代清理算法,年轻带采用的几乎都是标记复制算法,因为年轻代的对象大多数都会被GC掉,所以复制并不耗费多少时间。
- G1回收器的优点:
- 空间整合:标记整理算法,所以分配对象不会再触发一次GC
- 可以预测的停顿时间,因为基于Region,所以方便预测。
- G1的GC算法特点
- 整个堆都可以使用,年轻代和老年代都可以使用。
- 将堆分成若干不等大小的Region,这些Region既可以是年轻代,也可以是老年代。因为比传统的区域小,那么STW的时间预测粒度更细?【个人理解】
- 优先回收最大价值的Region【每次GC都记录下每个的价值】
- G1的新生代收集同ParNew类似,当新生代占用达到了一定比例,开始进行GC.
- G1的老年代同CMS一样会STW.
结语
当前项目采用的是JDK8
所以用的还是CMS
算法,听过一次唯品会的讲座,大意就是在整体堆内存小于8G的时候,CMS比G1稳定。
通过寒泉子的PerfMa
:https://opts.console.perfma.com/result/generate/zXx7y 发现也是这个结论。
所以当时做了如此选择。
骐骥一跃,不能十步。驽马十驾,功在不舍。