【问题标题】:Why does the garbage collector keep running in JDK 1.7?为什么垃圾收集器在 JDK 1.7 中继续运行?
【发布时间】:2013-03-07 13:41:46
【问题描述】:

我将 Oracle 1.7.0_10 VM 用于我正在运行的高性能 Java 应用程序。我花了很多时间使用 HPROF 分析器查看内存分配,因为它正在执行大量 GC(通过 -verbose:gc 输出测量)。现在,我做的分配很少,但 GC 仍然经常运行,做的工作很少,而且需要很长时间。例如,这是我在没有使用特殊 GC 选项时得到的一些输出 (-verbose:gc -XX:+PrintGCDetails -Xmx4g):

[GC [PSYoungGen: 21197K->96K(1228224K)] 420220K->399118K(2045440K), 0.0081950 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

[Full GC (System) [PSYoungGen: 96K->0K(1228224K)] [ParOldGen: 399022K->394779K(817216K)] 399118K->394779K(2045440K) [PSPermGen: 10758K->10758K(21248K)], 0.1503380 secs] [Times: user=0.89 sys=0.00, real=0.15 secs] 

[GC [PSYoungGen: 21195K->128K(1238592K)] 415974K->394907K(2055808K), 0.0061850 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 

[Full GC (System) [PSYoungGen: 128K->0K(1238592K)] [ParOldGen: 394779K->394779K(817216K)] 394907K->394779K(2055808K) [PSPermGen: 10758K->10758K(21248K)], 0.2534350 secs] [Times: user=1.71 sys=0.01, real=0.25 secs] 

这些一般消息在 2.5 秒的挂壁时间内重复 10 次 - 基于它们大约 250 毫秒的时间,这就是在那段时间里似乎正在做的所有过程(我知道它可能正在另一个线程上工作它)。让我感到困惑的是,似乎没有太多工作要做。查看消息,所有代似乎都有足够的空间 - Young 选择 21Mb->0,但分配了 1.2G,而老代的大小几乎没有变化,并且远低于它们的阈值。

鉴于此,为什么 GC 会如此频繁地运行?而且,在没有其他任何东西运行的情况下清理这么少的内存时,似乎也不应该在核心 i7 上花费 250 毫秒。

我尝试了其他 GC 参数,但似乎没有任何影响。不幸的是,由于我的应用使用 1.7 特定功能,因此我无法在任何其他 VM 中运行。

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

    鉴于此,为什么 GC 会如此频繁地运行?

    “Full GC (System)”通常表示您的应用程序已通过调用Runtime.getRuntime().gc()System.gc() 明确要求运行垃圾收集器。

    因此,您可能需要仔细检查您的代码。

    另外,请参阅Does java garbage collection log entry "Full GC (System)" mean some class called System.gc()?

    【讨论】:

    • 非常感谢 - 我使用了很多内部库,结果发现其中一个有 System.gc()。删除它后,额外的 GC 调用消失了,我的运行时间下降了 30%。
    • 可以使用-XX:+DisableExplicitGC让JVM忽略System.gc()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2011-10-30
    相关资源
    最近更新 更多