5

最初に、作成するオブジェクトの詳細を説明します。そして質問します(最後に)。

私は64を使用していますが、LinuxでJVMを使用しています。

私のjvmオプションは次のとおりです。 -Xmx6g -Xms3g -XX:MaxPermSize=256m

プロファイラー (jprofiler) は、大量のメモリを消費している 2 つの場所を示しています。他のいくつかの文字列の割り当てなども実行されますが、プロファイラーは StringUtils.replace がほとんどのメモリを保持していることを明確に示しています。2) ここでは、(単一クラスの) 4 つのオブジェクトを含むオブジェクト (3.5MB の場合は保持サイズ) が 1 分間に 1 つ作成され、静的な並行ハッシュマップに (再) 配置されます (したがって、マップには常に 1 つのオブジェクトのみが含まれます)。親オブジェクトが持っているのはこれら 4 つの子オブジェクトだけで、他には何もありません。これらの 4 つのオブジェクトのそれぞれには、10K の配列リスト、10K の日付、およびその他の文字列などが含まれています。古い親オブジェクト (map.replace() から取得したもの) を明示的に null に割り当て、(ArrayList.clear()) を明示的にクリアしています。 ArrayList、

メモリの動作は次のとおりです。メモリ使用量が増加し続け、ある時点でメジャー コレクション (2GB) が発生します。マイナー コレクション (700MB) も 1 分に 1 回程度発生します。

質問: #1 が実際に Eden スペースをいっぱいにして、JVM が #2 のオブジェクトを保有スペースにプッシュし、メモリ使用量がメジャー コレクションが発生するまで増加し続けると思いますか? 診断目的で、#2 の親オブジェクトを 500KB のサイズを保持するように変更しました (7 分の 1 で、Date、ArrayList などのインスタンスも 1.4K です)。それでも同じメモリ動作が見られます。

オプションを -Xmx12g -Xms3g -XX:MaxPermSize=256m -XX:NewSize=8g に変更しました 現在、メモリ内の #2 のオブジェクトの数が少ないことがわかります 保有スペース/古い世代の増加が遅いことがわかります。#2 のオブジェクトがすぐに収集されるのは良いことですが、マイナー コレクションが巨大 (8G) になり、2 分ごとに発生するため、CPU 使用率が非常に高くなります。

私の目標は、すべてのオブジェクトをすばやく収集することです (したがって、メモリ使用量が絶えず増加することはありません) が、マイナー コレクションが大きくなりすぎないようにします。

私が取るべきアプローチについて何か提案はありますか?

4

1 に答える 1

3

eden スペースを収集するコストは、保持されている eden スペース内のオブジェクトの数に比例します。コストが高いため、大部分のオブジェクトが 2 分以上保持されていることを示しています。

2 分ごとに約 6 GB のオブジェクト (NewSize には 2 つのサバイバー スペースが含まれます)、または 1 分あたり約 3 GB のオブジェクトを作成しているため、提案するサイズは 1 分あたりわずか数 MB であるため、この大部分はどこから来るのでしょうか。

3 GB がどこから来ているのかをよりよく理解し、それを減らすことが役立つと思います。

ところで: 1 分あたり 10 MB のガベージを作成する場合、10 時間で 6 GB しか作成されず、その間にマイナーまたはメジャー コレクションは必要ありません。

私が走れば

public class GCLikeMad {
    public static void main(String... args) {
        for(Long l = 0L; l < Integer.MAX_VALUE * 10L; l++);
    }
}

-XX:NewSize=256mなるほど_

[GC 295664K->240K(2121792K), 0.0011190 secs]
[GC 286832K->240K(2113216K), 0.0011510 secs]
[GC 278384K->240K(2105216K), 0.0012900 secs]
[GC 270256K->240K(2097280K), 0.0010110 secs]
[GC 262448K->240K(2257280K), 0.0013450 secs]

-XX:newSize=8g -verbosegcなるほど_

[GC 6291664K->320K(7345408K), 0.0017790 secs]
[GC 6291776K->272K(7345408K), 0.0021570 secs]
[GC 6291728K->272K(7345408K), 0.0014490 secs]
[GC 6291728K->240K(8393600K), 0.0016680 secs]
[GC 8388080K->208K(8393600K), 0.0018730 secs]

-XX:NewSize=30g -mx31g -XX:SurvivorRatio=100 -verbosegcこの時点で、32 ビット参照とメモリの NUMA 領域が 1 つだけ使用されます。

[GC 30840864K->256K(31154304K), 0.0014270 secs]
[GC 30840832K->256K(31154304K), 0.0014730 secs]
[GC 30840832K->224K(31154304K), 0.0016500 secs]
[GC 30840800K->272K(31154304K), 0.0015740 secs]
[GC 30840848K->272K(31462336K), 0.0015280 secs]

-XX:NewSize=128g -mx130g -XX:SurvivorRatio=100 -verbosegcそれは違いを生み始めます。注: この時点で、メモリの複数の NUMA 領域と 64 ビット参照が使用されています。これは2分ごとに収集しています。

[GC 131586048K->320K(132907264K), 0.0042360 secs]
[GC 131586368K->1376K(132907264K), 0.0058030 secs]
[GC 131587424K->1440K(132907264K), 0.0034110 secs]

この時点で、3 つのコレクションのみで 200 億の Long オブジェクトを作成していました。

128 GB の Eden スペースは巨大だと思います。:D


私のポイントは、eden のサイズを大きくしても、GC 時間だけが増えるわけではないということです。保持されるオブジェクトの数が増えると、所要時間が長くなります。

于 2012-04-11T17:41:27.573 に答える