阅读量 : 90次
相比于大多数垃圾回收器,C4的不同之处在于它认为垃圾回收并不是什么坏事(即应用程序产生垃圾很正常),而压缩是不可避免的。在设计之初,C4就是要牺牲各种动态内存管理的需求,以满足需要长时间运行的服务器端应用程序的需求。
C4算法将释放内存的过程从应用程序行为和内存分配速率中分离出来,并加以区分。这样就实现了并发运行,即应用程序可以持续运行,而不必等待垃圾回收的完成。其中的并发性是关键所在,正是由于并发性的存在才可以使暂停时间不受垃圾回收周期内堆上活动数据数量和需要跟踪与更新的引用数量的影响,将暂停时间保持在较低的水平。
大多数垃圾回收器在工作周期内都包含了stop-the-world式的压缩过程,这就是说应用程序的暂停时间会随活动数据总量和堆中对象间引用的复杂度的上升而增加。使用C4算法的垃圾回收器可以并发的执行压缩操作,即压缩与应用程序线程同时工作,从而解决了影响JVM伸缩性的最大难题。
(2)重定位(Relocation) — 将存活对象移动到一起,以便可以释放较大的连续空间,这个阶段也可称为“压缩(compaction)”
(3)重映射(Remapping) — 更新被移动的对象的引用。

在C4算法中,标记阶段(marking phase)使用了并发标记(concurrent marking)和引用跟踪(reference-tracing)的方法来标记活动对象,这是C4算法与其他并发标记器的工作方式相同的地方。不同之处在于并发标记阶段中,如果应用程序线程修改未标记的对象,那么该对象会被放到一个队列中,以备遍历。这就保证了该对象最终会被标记,也因为如此,C4垃圾回收器或另一个应用程序线程不会重复遍历该对象。这样就节省了标记时间,消除了递归重标记(recursive remark)的风险。
C4算法是基于LVB(load value barrier)实现的,LVB具有自愈能力,可以使应用程序线程迅速查明某个引用是否已经被标记过了。如果这个引用没有被标记过,那么应用程序会将其添加到GC队列中。一旦该引用被放入到队列中,它就不会再被重标记了。应用程序线程可以继续做它自己的事。
在C4算法中,并没有重标记(re-marking)这个阶段,在第一次便利整个堆时就会将所有可达对象做标记。因为运行时不需要做重标记,也就不会陷入无限循环的重标记陷阱中,由此而降低了应用程序因无法分配到内存而抛出OOM错误的风险。
C4算法中,重定位阶段(reloacation phase)是由GC线程和应用程序线程以协作的方式,并发完成的。这是因为GC线程和应用程序线程会同时工作,而且无论哪个线程先访问将被移动的对象,都会以协作的方式帮助完成该对象的移动任务。因此,应用程序线程可以继续执行自己的任务,而不必等待整个垃圾回收周期的完成。
上一篇: 2023新年寄语---合作携手迈入新一年
下一篇: 多彩端午,乐在其粽
返回顶部