为什么垃圾收集器在JDK 1.7中继续运行?

use*_*429 2 java garbage-collection

我正在使用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] 
Run Code Online (Sandbox Code Playgroud)

这些一般消息在2.5秒的挂起时间内重复10次 - 基于它们大约250ms的时间,这是在此期间似乎正在进行的所有过程(我理解它可能正在另一个线程中为其中一些工作).令我感到困惑的是,似乎没有太多工作要做.看看这些消息,所有代人似乎都有足够的空间 - 杨为21Mb-> 0,但它分配了1.2G,老一代的规模几乎没有变化,远远低于他们的门槛.

鉴于此,为什么GC会经常运行?它看起来似乎并不存在它应该在核心i7上花费250ms而没有其他任何东西来清理这么少的内存.

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

NPE*_*NPE 6

鉴于此,为什么GC会经常运行?

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

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

另外,请参阅java垃圾收集日志条目"Full GC(System)"是否意味着一些名为System.gc()的类?