老年代需要多满才能触发一个主要的 GC 循环?

bob*_*ina 5 java size garbage-collection heap-memory

我正在努力解决我们生产环境中垃圾回收利用率高的问题,并且想知道是否设置一个大堆大小来保证老年代永远不会被真正填满会阻止触发一个主要的 GC 周期。

要做到这一点,我想有一个特定的阈值标记,在该阈值标记处触发了一个主要的 GC 循环。如果这个假设是真的,有人可以让我知道那个数字是多少吗?如果没有,我希望能解释一下这些主要循环是如何实际触发的,以及我的大堆策略是否有工作潜力。

tol*_*ius 6

并发标记扫描

假设您使用 Concurrent Mark Sweep 收集器(例如-XX:+UseConcMarkSweepGC),默认情况下,当 OldGen 达到70%时,它开始并发收集。但它可以通过CMSInitiatingOccupancyFraction例如:

-XX:CMSInitiatingOccupancyFraction=42
Run Code Online (Sandbox Code Playgroud)

这将以 42% 与默认的 70% 开始并发收集

请注意,CMSInitiatingOccupancyFraction这仅对第一个集合有效。要“永久”启用它,请添加UseCMSInitiatingOccupancyOnly

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=42
Run Code Online (Sandbox Code Playgroud)

最大堆空闲率

您还可以查看在GC之后避免收缩MaxHeapFreeRatio的最大堆空闲百分比,默认情况下设置为70%,但您也可以更改它:

-XX:MaxHeapFreeRatio=42
Run Code Online (Sandbox Code Playgroud)

到达底部

但是在更改任何参数之前,最好先了解这种“垃圾回收利用率高”的原因:

  • 如果需要如此频繁地收集它,为什么它会到达 OldGen?
  • 您是否正在捕获流数据?
  • 堆大小是否太小导致问题?
  • 将这些特定数据存储在堆外是否有意义?
  • 等等..

因为通常 JVM 非常擅长知道何时收集,而且它只会变得更好。


其他H?tSpot VM 选项