说明
- 本文摘自The Garbage-First Garbage Collector并进行部分转译。
- 本人水平有限,如有纰漏,欢迎指出,感激不尽。
介绍
G1垃圾回收器在Oracle JDK 7u4之后完整支持,G1是server型的垃圾回收器,主要是针对多颗处理器和有大内存的机器,它可以高概率的匹配停顿时间目标,同时还实现高吞吐量。在整个堆的操作中,像一些全局标记,是可以和应用程序线程并发进行的,这还可以防止与堆或数据大小成比例的中断。
技术描述
堆被划分为一组大小相等的堆区域,每一个连续的虚拟内存范围。G1通过全局并发标记来找出堆中的存活对象。在标记阶段完成后,G1就知道哪些区域基本为空,这些区域首先会被回收,因为这样通常可以产生大量的空闲空间,这就是把这种垃圾回收方式称为G1的原因。正和名字所暗示的意思,G1将回收和压缩活动集中在堆的区域上,这些区域可能充满可被回收的对象,也就是垃圾。G1使用一个暂停预测模型来满足用户定义的停顿时间目标以及根据指定的停顿时间目标来选择要回收区域的数量。
被G1识别出来的区域是会被认为是可被立即回收的垃圾区域,G1会从堆的一个或多个区域中复制对象到堆的某一个区域,在复制过程中会一边压缩一边释放相应的内存空间,这个做法在多处理器上是并行进行的,目的是为了减少停顿时间并提高吞吐量。另外,对于每一个垃圾回收器来说,G1会持续运行以减少碎片,并同时满足用户定义的停顿时间目标,这超出了前面两种方法的能力,CMS回收器并没有进行压缩操作,并行回收垃圾回收也只是在整个堆进行压缩的时候才进行,但这个也会导致相当大的停顿时间。
G1有个需要注意的地方就是它不是实时回收器,它会尽量的去满足停顿时间目标,但这个并不是绝对可靠。来自前一个回收器的数据基础上,G1在用户定义的目标时间内做了大量预测哪些区域会被回收的工作,因此,回收器对于是否回收该区域已经有一个相当准确的模型,并利用这些模型来判断在目标停顿时间内该回收哪些区域,
想要了解更多关于如何使用和配置G1的信息,请查看命令行选项。
使用G1的一些建议
首先就是G1为用户运行在GC限制下还需要大堆的应用程序提供了一种解决方案,这就意味着堆大小可以达到6GB或更大,并且停顿时间还可以稳定在0.5秒之内。
在今时今日所运行的应用程序中,如果应用程序有以下一种或多种情况,那么应用程序使用G1回收器就会比使用CMS或并行回收器更能获得更好的受益:
- java堆中50%以上都是存活对象
- 对象分配率或推进率不明显
- 不期望长的垃圾回收或压缩停顿时间(超过0.5到1秒)
将来
长期来说,G1就是计划来替换CMS的,G1和CMS对比,其中有很多不同点使得G1是一种更好的解决方法,其中一种不同就是G1是压缩型的回收器,G1要充分完成压缩会避免使用细粒度的免费列表进行分配,而依赖于区域,对于回收器来说,这里并没有考虑太多,而更大的重心在于碎片问题解决,因此,G1比CMS更能提供更为准确的垃圾回收停顿时间,并还允许用户设置期望的停顿时间目标。