我将 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 中运行。