実行している高性能JavaアプリにOracle1.7.0_10VMを使用しています。HPROFプロファイラーが大量のGCを実行していたため(-verbose:gc出力で測定)、HPROFプロファイラーでメモリ割り当てを調べることに多くの時間を費やしました。現在、私はほとんど割り当てを行っていませんが、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回繰り返されます-約250msのタイミングに基づいて、これがその時間中に行われているように見えるすべてのプロセスです(一部のスレッドで別のスレッドで作業を行っている可能性があることを理解しています)。私を混乱させているのは、多くの作業が行われているようには見えないということです。メッセージを見ると、すべての世代に十分なスペースがあるようです。Youngは21Mb-> 0になりますが、1.2Gが割り当てられており、Old世代のサイズはほとんど変化せず、しきい値をはるかに下回っています。
これを考えると、なぜGCはそれほど頻繁に実行され続けるのですか?そして、とにかくそれはコアi7で250msかかるはずであり、他に何も実行されていないので、メモリをクリーンアップする必要はないようです。
他のGCパラメータを試しましたが、影響があるようには見えません。残念ながら、私のアプリは1.7固有の機能を使用しているため、他のVMでは実行できません。