有关G1的并行完整GC的说明

时间:2018-05-05 04:22:49

标签: java garbage-collection

作为java JDK10的一部分,JEP307被Parallel Full GC for G1实现了。

我试图理解它的描述,但我仍然不相信我的想法得当。

我的怀疑是它与并发垃圾

有关

7 个答案:

答案 0 :(得分:9)

作为简化说明 - 垃圾收集器有两种可能的收集类型,"增量"和#34;完整"。增量收集是最好的两种方式,因为它会经常做一些工作。完全收集通常更具破坏性,因为它需要更长的时间并且经常在运行时停止整个程序执行。

因此,大多数现代GC(包括G1)通常会尝试确保在正常情况下,增量收集就足够了,永远不需要完整的收集。但是,如果不同世代的大量对象有可能以不可预测的方式进行垃圾收集,那么偶尔完整的GC可能是不可避免的。

目前,G1完整集合实现只是单线程。这就是JEP的用武之地 - 它旨在并行化它,这样当一个完整的GC确实发生时,它可以在支持并行执行的系统上更快。

答案 1 :(得分:6)

最后,我了解了G1的并行完整GC

enter image description here

在JDK 9中使用默认值并在JDK 7中引入

有效地同时处理堆垃圾收集失败  有时完全垃圾收集是不可避免的。它有效地同时处理非常大的堆正常GC将堆分成年轻(伊甸园和幸存者)和 老一代(逻辑分离)G1将堆分成许多小区域。这种分裂使G1能够选择一个小区域来快速收集和完成。

在JDK9中使用单线程进行完整GC

在JDK 10中使用多线程(并行)进行垃圾收集'

答案 2 :(得分:5)

G1垃圾收集器旨在避免完整集合,但是当并发集合无法足够快地回收内存时,将发生后退完整GC。 G1的完整GC的当前实现使用单线程标记 - 扫描 - 紧凑算法。我们打算并行化mark-sweep-compact算法,并使用与Young和Mixed集合相同数量的线程。线程数可以通过-XX:ParallelGCThreads选项控制,但这也会影响用于Young和Mixed集合的线程数。

答案 3 :(得分:3)

G1垃圾收集器因单线程完整GC循环而臭名昭着。当您需要所有可以为未使用的对象进行搜索的硬件时,我们会在单个线程上遇到瓶颈。在Java 10中他们解决了这个问题。完整的GC现在运行我们投入的所有资源。 为了证明这一点,我编写了ObjectChurner,它创建了一堆不同大小的字节数组。它保留了一段时间的物体。尺寸是随机的,但是以可控,可重复的方式。

答案 4 :(得分:3)

Java 10通过迭代改进其现有算法来减少完整GC暂停时间。直到Java 10 G1 Full GC在单个线程中运行。那是对的 - 你的32核心服务器和它的128GB将停止并暂停,直到一个线程取出垃圾。在Java 10中,这已被改进为并行运行。这意味着Full GCs将并行处于多个线程上,尽管在完成时仍然会暂停JVM的进度。可以使用-XX:ParallelGCThreads选择性地配置线程数。

这是对Java 10中G1算法的一个很好的改进,它可以减少大多数用户的最坏情况暂停时间。这是否意味着Java GC暂停已成为过去?否 - 它减少了问题,但由于G1不会与您的应用程序同时运行其收集周期,因此它仍将定期暂停应用程序,并且Full GC暂停仍会随着堆大小的增加而增加。我们在上一篇博文中谈到了其他一些垃圾收集器,可能会在将来解决这个问题。

答案 5 :(得分:2)

G1收藏家
使用Java 8更新20的另一个漂亮的优化是G1收集器字符串重复数据删除。由于字符串(及其内部char []数组)占用了我们的大部分堆,因此进行了一项新的优化,使G1收集器能够识别在堆中多次复制的字符串,并将它们更正为指向相同的内部字符串[]数组,以避免相同字符串的多个副本在堆内无效地驻留。您可以使用-XX:+UseStringDeduplicationJVM参数来尝试此操作。

G1GC中的并行完整GC
G1垃圾收集器因进行单线程完整GC循环而臭名昭着。当您需要所有可以为未使用的对象进行搜索的硬件时,我们会在单个线程上遇到瓶颈。在Java 10中他们解决了这个问题。完整的GC现在可以运行我们投入的所有资源。

JVM参数:-Xlog:gc,gc+cpu::uptime -Xmx4g -Xms4g -Xlog:gc*:details.vgc这会将每个GC事件及其CPU使用情况输出到stdout,仅显示正常运行时间作为标记。设置-Xlog:gc*类似于以前Java版本的-XX:+PrintGCDetails

答案 6 :(得分:1)

Java 10通过迭代改进其现有算法来减少完全GC暂停时间。直到Java 10 G1 Full GC在单个线程中运行。没错-您的32核心服务器以及128GB的磁盘将停止并暂停,直到有一个线程将垃圾清除。在Java 10中,已对其进行了改进,使其可以并行运行。这意味着完整的GC将并行运行在多个线程上,尽管在完成时JVM的进程仍然暂停。可以选择使用-XX:ParallelGCThreads.

配置线程数