如何理解垃圾回收频繁的原因?
How do I understand the reason for frequent garbage collection?
jstat -gc 27539
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
901632.0 468480.0 0.0 0.0 911360.0 911360.0 5464064.0 5463748.3 21632.0 20948.0 2944.0 2777.7 153 33.727 401 782.598 816.325
jstat -gccapacity 27539
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
171008.0 2732032.0 2714624.0 901632.0 468480.0 911360.0 343040.0 5464064.0 5464064.0 5464064.0 0.0 1069056.0 21632.0 0.0 1048576.0 2944.0 153 404
我添加了 EU
和 OU
来查找使用的总堆。看起来使用了 6GB。我提到了 this
但是发生了 400 多次 FGC。现在已经达到700+了。一段时间后,它只是执行 GC。现在850+了
我的工作:
是多线程。 100 reader,100 个编写线程。每个都有自己的数据库连接。每个 reader 线程读取 100000 条记录并存储在 LinkedList
中并发送到 writer 线程。 Writer
将数据写入同一数据库中的另一个集合。 LinkedList 不被重用意味着每 1L 创建一个新的 LinkedList。
它是基于akka
的多线程。所以我不处理线程故障、线程生成,即线程管理。
但我怀疑为什么当我有 32gb 内存时会发生如此巨大的 FGC?任何进一步观察的指示?
它 运行 进入 GC Overhead LIMIt exceeded error sometimes.
我没有为作业设置任何明确的最小、最大内存。
编辑:
根据我的分析,它修复了一些 EU
和 OU
。它已满,因此继续执行 GC。这可能吗?我说得对吗?
编辑2
感谢@emotionlessbanans,@Cascader。我有下面的。
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 526385152 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 8392802304 {product}
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
当我有 8GB 时,有什么特定的原因可以停止在 6GB 吗?还是我遗漏了什么?
未指定默认最小内存,最大为 256Mb。分配给堆的内存不足可能是问题。 (这是我的怀疑)
您也可以使用 VisualVM 或任何其他可能显示有关那里发生的事情的更多信息的工具。
当未使用 -Xmx
开关指定最大堆大小时,JVM 选择默认值。该值是特定于 JVM 供应商的,通常取决于体系结构(32/64 位)和可用内存总量。
您的应用程序似乎使用了所有分配的内存(由您的 JVM 确定的内存)并且从某个时候开始它在 GC 上花费了太多时间,直到出现“超出 GC 开销限制”错误。
您应该明确设置最大堆大小(即 -Xmx 10g
)以确保您使用所有可用内存。
jstat -gc 27539
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
901632.0 468480.0 0.0 0.0 911360.0 911360.0 5464064.0 5463748.3 21632.0 20948.0 2944.0 2777.7 153 33.727 401 782.598 816.325
jstat -gccapacity 27539
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
171008.0 2732032.0 2714624.0 901632.0 468480.0 911360.0 343040.0 5464064.0 5464064.0 5464064.0 0.0 1069056.0 21632.0 0.0 1048576.0 2944.0 153 404
我添加了 EU
和 OU
来查找使用的总堆。看起来使用了 6GB。我提到了 this
但是发生了 400 多次 FGC。现在已经达到700+了。一段时间后,它只是执行 GC。现在850+了
我的工作:
是多线程。 100 reader,100 个编写线程。每个都有自己的数据库连接。每个 reader 线程读取 100000 条记录并存储在 LinkedList
中并发送到 writer 线程。 Writer
将数据写入同一数据库中的另一个集合。 LinkedList 不被重用意味着每 1L 创建一个新的 LinkedList。
它是基于akka
的多线程。所以我不处理线程故障、线程生成,即线程管理。
但我怀疑为什么当我有 32gb 内存时会发生如此巨大的 FGC?任何进一步观察的指示?
它 运行 进入 GC Overhead LIMIt exceeded error sometimes.
我没有为作业设置任何明确的最小、最大内存。
编辑:
根据我的分析,它修复了一些 EU
和 OU
。它已满,因此继续执行 GC。这可能吗?我说得对吗?
编辑2
感谢@emotionlessbanans,@Cascader。我有下面的。
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 526385152 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 8392802304 {product}
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
当我有 8GB 时,有什么特定的原因可以停止在 6GB 吗?还是我遗漏了什么?
未指定默认最小内存,最大为 256Mb。分配给堆的内存不足可能是问题。 (这是我的怀疑)
您也可以使用 VisualVM 或任何其他可能显示有关那里发生的事情的更多信息的工具。
当未使用 -Xmx
开关指定最大堆大小时,JVM 选择默认值。该值是特定于 JVM 供应商的,通常取决于体系结构(32/64 位)和可用内存总量。
您的应用程序似乎使用了所有分配的内存(由您的 JVM 确定的内存)并且从某个时候开始它在 GC 上花费了太多时间,直到出现“超出 GC 开销限制”错误。
您应该明确设置最大堆大小(即 -Xmx 10g
)以确保您使用所有可用内存。