【问题标题】:Repeated Full GC with available Heap具有可用堆的重复 Full GC
【发布时间】:2013-10-02 20:42:45
【问题描述】:

即使堆没有完全使用,我也会重复 Full GC。

这是 gc 日志的样子:http://d.pr/i/iFug(蓝线是已使用的堆,灰色矩形是 Full GC)。

好像是和本题贴的类似的问题:Frequent full GC with empty heap

但是,该线程没有提供任何实际问题的答案。我的应用程序确实使用 RMI,并且生产服务器在升级 45 之前确实使用 1.6,这将 GC 间隔从 1 分钟增加到 1 小时 (http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/relnotes.html)。但是,从日志的其余部分来看,我看不到 Full-GC-every-1-min 模式。

这可能是什么原因造成的?

【问题讨论】:

    标签: java memory-leaks garbage-collection jvm heap-memory


    【解决方案1】:

    最有可能的原因是您已达到堆的当前大小。堆的大小小于您设置的最大值,并在程序运行时进行调整。

    例如假设您设置的最大值为 1 GB,初始堆大小可能为 256 MB,当您达到 256 MB 时,它会执行一次完整的 GC,在此 GC 之后,它可能会决定 400 MB 将是更好的大小,当达到执行full GC等。


    当永久空间填满或无法找到可用空间时,您将获得一个主要集合。例如,如果它是碎片化的。

    如果您的幸存者空间太小,您也可以获得完整的收藏。

    简而言之,最可能的原因是您使用的 gc 调优参数。我建议您简化调整参数,直到您的系统以您期望的方式运行。

    【讨论】:

    • 我正在使用相同的最小和最大堆启动 JVM,所以不可能。我很想尝试调整 GC,但不幸的是,这发生在生产环境中,我能够在测试环境中重现它。
    【解决方案2】:

    如链接线程中所述,禁用显式 GC 并查看 FullGC 模式是否再次出现:-XX:+DisableExplicitGC。 RMI 代码可能会在给定的时间间隔内触发显式 GC,这在某些情况下可能是不可取的。

    如果 FullGC 仍然发生,我会使用线程转储和可能的堆转储来分析问题。

    另外,使用jstat查看Eden、Survivor、OldGen空间的占用情况。

    【讨论】:

    • 这可行,但会有什么副作用?我很想在测试环境中重现它,但我做不到。
    • 不应该有任何副作用,不鼓励调用System.gc() - 这可能会损害性能,因此建议只使用-XX:+DisableExplicitGC 并让GC 完成工作。你基本上使用这个标志来防止试图触发显式 GC 的流氓库/代码。
    猜你喜欢
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多