作者回复: 赞!
作者回复: 1. 采用并行GC可以减少需要STW的时间。它们会在即时编译器生成的代码中加入写屏障或者读屏障。
2. Y轴应该是时间,那毛刺就是长暂停。一般Full GC就会造成长暂停。
3. 通过调整新生代大小,使对象在其生命周期内都待在新生代中。这样一来,Minor GC时就可以收集完这些短命对象了。
作者回复: 这是C2一个诡异的地方。
for (int i=start; i<limit; i++) {..}
对于int类型的循环变量i,如果满足 1) 基于该循环变量的循环出口只有一个,即i < limit,2) 循环变量随着迭代的增量为常数,例子中i++即增量为1,以及循环变量的上限(当增量为负数时则是下限)为循环无关的,即limit应是循环无关,那么C2会将其判断成计数循环(counted loop),然后默认不插入safepoint。
而对于long类型的循环变量,C2直接识别为非计数循环,需要插入safepoint。
作者回复: 这里指的是,GC已经标记完成,然后其他线程进行修改的情况(也是并发GC所要解决的问题)。
当GC标记完成,还未开始回收时,你更新了其中一个引用,使之指向null,那么原来指向的对象本可以被回收的。
如果指向一个新的对象,这个对象可没有被标记为不能回收,垃圾回收器就直接给回收掉了
作者回复: 目前的垃圾回收器多多少少需要stop the world,但都在朝着尽量减少STW时间发展。
完全的并发GC算法是存在的,但是在实现上一般都会在枚举GC roots时进行STW。
作者回复: 确实是需要复制数据,这样起名主要是为了区分复制到同一个区域中(需要复杂的算法保证引用能够正确更新),还是复制到另一个区域中(可以复制完后统一更新引用)。
作者回复: 赞想法!不过我认为没有达到更好的回收效率,因为垃圾回收标记的是非垃圾,剩余没有标记的对象是垃圾。用引用计数法清理后,可达性分析仍需遍历所有活着的对象。
但是可以将引用计数做成minor minor GC,只有当引用计数回收不了垃圾时,再触发可达性分析。感兴趣的话可以深入探索一下业界其他非Java runtime的垃圾回收算法。