垃圾回收超时限制已超过阈值

93

JVM在抛出 'java.lang.OutOfMemoryError : GC overhead limit exceeded' 异常时使用的采样时间是多少?我知道你可以使用参数 GCTimeLimit 和 GCHeapFreeLimit 控制98%和2%,但采样时间是多少?

1个回答

82

以下内容摘自Java SE 6 HotSpot [tm]虚拟机垃圾回收调整

下文与另一段落结合使用

过度的GC时间和OutOfMemoryError

如果在垃圾回收中花费的时间超过了总时间的98%,并且回收了不到2%的堆空间,那么并发收集器会抛出OutOfMemoryError。此功能旨在防止应用程序由于堆太小而无法取得任何或取得很少进展而运行很长时间。如果需要,可以通过添加选项-XX:-UseGCOverheadLimit到命令行来禁用此功能。

该策略与并行收集器相同,只是不将执行并发收集所花费的时间计入98%时间限制。换句话说,只有应用程序停止时执行的垃圾收集才算作过度的GC时间。这种回收通常是由于并发模式失败或显式收集请求(例如调用System.gc())引起的。

显式垃圾回收最常见的用途之一是RMI分布式垃圾回收(DGC)。使用RMI的应用程序会引用其他虚拟机中的对象。在这些分布式应用程序中,无法回收垃圾而不偶尔收集本地堆,因此RMI会定期强制执行完整的垃圾收集。可以使用属性控制这些收集的频率。例如:

java -Dsun.rmi.dgc.client.gcInterval=3600000

-Dsun.rmi.dgc.server.gcInterval=3600000指定每小时一次的显式垃圾回收,而不是默认频率每分钟一次。然而,这也可能导致某些对象需要更长时间才能被回收。如果不希望在DGC活动及时性上设置上限,则可以将这些属性设置为Long.MAX_VALUE,以使显式集合之间的时间实际上无限制。

似乎暗示确定98%的评估期为一分钟,但使用正确的定义可以在Sun的JVM上进行配置。

当然,也可能存在其他解释。


5
RMI分布式垃圾收集与常规垃圾收集无关。因此,我不明白你是如何推断出刚才所说的内容的。 - Stephen C
2
推断并不完美或正确,这就是为什么使用“似乎意味着”而不是“意味着”。如果您同意这样的观察结果:如果Sun公司的人在确定RMI的垃圾收集间隔时使用了一分钟,那么当主程序停止时,同时收集时间只会累积计算,然后进行一些跳跃性的思考,那么98%在一分钟内被收集的几率很大。这是一个神奇的数字,但一分钟经常与3.5分钟进行比较。 - Edwin Buck
@StephenC,您的意思是即使我们设置了“-XX:+ DisableExplicitGC”,它也不会影响RMI相关配置,并且系统将按照参数“-Dsun.rmi.dgc.server.gcInterval”设置的频率调用gc。 - Steephen
1
@Steephen - 不是,我说的不是那个意思。我在谈论这句话:“似乎暗示确定98%的评估期为一分钟…”。请注意,Edwin同意这种推断是“不完美”的。这种推断基于这样一个假设:实现RMI(和DGC)的Sun工作人员与实现GC开销限制机制的工作人员之间进行了密切的沟通。我怀疑这两种发展实际上是在不同的时间发生的。请注意,-Dsun.rmi.dgc.server.gcInterval属性自Java 1.2以来就存在。 - Stephen C
1
无论如何,找到这个问题的真正答案的更好方法是查看OpenJDK源代码。 - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接