【问题标题】:JVM: Why does my S0C Area have a size of zero?JVM:为什么我的 S0C 区域的大小为零?
【发布时间】:2020-03-12 15:48:49
【问题描述】:

我在我的应用程序中看到了大量的年轻代垃圾回收。这是一个在 openJDK 8u212 上运行的 scala 应用程序。我在正在运行的 docker 容器上做了一个 jstat,它显示 S0C 区域的大小为零。这可以解释为什么我会得到这么多年轻的 GC,但我不知道为什么会这样。

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
 0.0   2048.0  0.0   2048.0 36864.0  31744.0   706560.0   644022.6  93360.0 82013.4 11184.0 9627.5  15299  126.920   0      0.000  126.920

关于如何进一步调查此问题的任何想法?这些是我的 JVM_OPTS。

"-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/mnt/mesos/sandbox/ -Xmx3g -XX:+UseG1GC -XX:+UseStringDeduplication 

我找不到任何可用于控制 S0C 大小的 JVM 选项。

【问题讨论】:

  • 当 Eden 空间已满时,你会得到一个 Young GC。 Survivor 空间可能会因为 GC 而被填满,而不是相反。由于在每次 GC 之间,两个幸存者空间之一永远不能包含对象,因此将其报告为零容量并没有错。
  • 在 G1GC 的情况下,空格在内存中是不固定的。 G1GC 将堆划分为区域,根据需要将这些区域分配给逻辑空间之一。因此,始终为空的幸存者空间确实与实际的内存区域无关。
  • 您使用的是什么 Java 版本(UseCGroupMemoryLimitForHeap 已弃用)以及您有什么 确切 GC?这在正确和完整的答案中很重要

标签: java scala garbage-collection jvm


【解决方案1】:

当伊甸园空间已满时,会触发次要垃圾回收(由伊甸园和幸存者空间组成)。当触发次要垃圾回收时,未引用的对象(在伊甸园和幸存者中)被删除,被引用的对象年龄增加,被引用的对象被移动到其他幸存者空间。伊甸园和幸存者空间被清除。这个循环一直持续到老化对象达到某个年龄阈值。当对象达到一定的年龄阈值时,它们会从年轻代提升到老年代。 正如 Holger 所说,两个幸存者空间之一永远不能包含对象。

参考资料:

【讨论】:

  • 嗯,所以任何时候都只有一个幸存者空间被填充?这就说得通了。你在我的 jstat 结果中看不到的是,因为它只有一行,所以两个幸存者空间正在切换。我希望当 Eden 满时,其他幸存者空间应该在次要 GC 之后填充。相反,我看到的是一个完全填充的 Eden 和 S1C,并且没有切换 - 即使我每秒记录大量的次要 GC。
  • @suleydaman 较旧的 GC 算法确实具有与幸存者空间相关联的固定内存区域,并且切换对它们有意义。由于 G1GC 动态分配内存区域,因此切换不再有意义。只有一个幸存者空间和以前分配给幸存者空间的未使用区域。
猜你喜欢
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2021-11-11
相关资源
最近更新 更多