【发布时间】:2011-02-21 06:45:26
【问题描述】:
有时,在每 2 天一次到每 2 周一次之间,我的应用程序在代码中看似随机的位置崩溃:java.lang.OutOfMemoryError: GC overhead limit exceeded。如果我用谷歌搜索这个错误,我会找到this SO question,这会导致我找到this piece of sun documentation,这说明:
如果时间过长,并行收集器将抛出 OutOfMemoryError 用于垃圾收集:如果超过 98% 的总时间是 花费在垃圾收集上,只有不到 2% 的堆被回收, OutOfMemoryError 将被抛出。此功能旨在防止 应用程序在制作过程中长时间运行 由于堆太小,很少或没有进展。如有必要,这 可以通过将选项 -XX:-UseGCOverheadLimit 添加到 命令行。
这告诉我,我的应用程序显然将 98% 的总时间用于垃圾收集,只恢复了 2% 的堆。
但是 98% 的时间是什么时候?整个两周的 98% 的应用程序一直在运行?最后一毫秒的 98%?
我正在尝试确定实际解决此问题的最佳方法,而不仅仅是使用-XX:-UseGCOverheadLimit,但我觉得有必要更好地了解我正在解决的问题。
【问题讨论】:
-
从文档来看,这似乎是整个 2 周的 98%。您是否使用这些标志启用了 GC 日志 -verbose:gc -XX:+PrintGCDetails XX:+PrintGCTimeStamps –Xloggc:PATH_FROM_ROOT/gclog.log。很高兴看到应用程序运行时间和由于 GC 而停止的时间。
-
GC 日志记录是一个不错的建议,我会尝试的。 98% 的 2 周似乎不太可能,但你是对的,这就是文档所暗示的。我希望这只是不精确的写作
-
你找到98%时间的含义了吗?我的观点是,GC 应该在异常发生的那一刻忙于占用 98% 的应用程序利用率,而不是在 2 周内。
-
@Monis:我还没找到,放弃找了。 98% 的时间“在这一刻”没有多大意义,因为从定义上看,一个时刻不是一段时间,所以“98% 的时刻”也不可能是(而且和“长”一样2% 的时间)。
标签: java garbage-collection out-of-memory