java - G1算法中的 memset 有什么用?

标签 java jvm g1gc

我刚刚阅读了一些关于 G1 算法的博客。

记住集合的用法让我感到困惑。

这是我的想法:

既然我们可以使用 DFS 遍历来自 GC-Roots 的每个引用,为什么我们需要记住集?

导致所有的博客都说我们使用remembered-set的原因是我们不需要检查每个region来查看是否有GC-Roots引用的对象

最佳答案

您需要了解什么Card Table首先,海事组织。你怎么只扫描young generation区域并清理它,如果有来自 old generation 的引用返回 young ?您需要准确地“跟踪”这些连接所在的位置 - 因此在扫描时 young generation你可以在不破坏堆的情况下清理它。

想一想:您不能将对象标记为移除 A现在是年轻代,如果有引用B到它,来自 old generation .但现在请记住——你只是在年轻的系列中。所以要跟踪这些“连接”Card Table被执行。这张卡片表中的每一位都表示老年代的某个部分是“脏的”,这意味着在扫描年轻代的同时也扫描老年代的那部分。

你为什么需要那个?扫描年轻的整个点是扫描堆的一小部分,而不是全部。此 card table做到了这一点。
G1有地区。如果您正在扫描怎么办 regionA你会看到它有指向其他一些 regionB 的指针?只需将此信息放入 Card Table是不足够的。你的牌 table 只会知道regionA ,下次扫描时 regionB - 你怎么知道你应该扫描 regionA还?如果你不这样做,显然堆完整性被破坏了。

因此:remembered sets .这些集合由一个异步线程填充:它扫描 card table并根据该信息,它还扫描这些“脏”区域的指针指向的位置。它跟踪该 regionA -> regionB联系。每个地区都有自己的remembered set .

所以当你到达GC需要发生的点时,扫描regionB时你也看看它的remembered set并发现您还需要扫描regionA .

实际上,这就是为什么 G1成为世代:这些 remembered sets结果是巨大的。如果在young中划分堆和 old ,没有必要保持年轻代之间的联系,无论如何你都会一次扫描它们,从而消除这些集合大小的问题。 G1想保留那个 200ms (默认)promise - 为此,您需要一次扫描所有年轻代(因为 remembered sets 中的区域之间没有连接,否则堆完整性将消失),但同时如果您使年轻代变小 - remembered sets的尺寸会很大。

因此,恕我直言,触摸这些设置是一个工程奇迹。

关于java - G1算法中的 memset 有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61936621/

相关文章:

scala - Spark : shuffle operation leading to long GC pause

java - 编译包含所有需要的外部源的 jar 文件

java - Android(Archos 5 IT)上的音频(MediaPlayer)

java - 如何在 Jython 中拦截键盘中断 (CTRL-C)?

java - 直接分配给老年代

java - G1 gc 上 "Ext Root Scanning"的文档/代码/详细说明?

java - 在 Fxml 中添加时 CustomTextField 不起作用

java - 在 Android 中持续更新 UI 线程的最有效方法

scala - Scala 和 Jython 的互操作性

java - 为什么 G1GC 日志中对堆使用情况的描述不同