3

3G の開始ヒープ サイズ (-Xms3072m VM 引数で設定) で Java プログラムを実行すると、JVM はそのサイズで開始しません。400m 程度から開始し、必要に応じてさらにメモリを取得し続けます。

これは私にとって深刻な問題です。しばらくすると、JVMが上記の量を必要とすることを私は知っています。また、必要に応じて JVM のメモリが増加すると、速度が低下します。JVM がより多くのメモリを取得する間、かなりの時間がガベージ コレクションに費やされます。そして、メモリの獲得は高価な作業だと思います。

JVM が実際に開始ヒープ サイズ パラメータを尊重していることを確認するにはどうすればよいですか?

更新:このアプリケーションは多くのオブジェクトを作成しますが、そのほとんどはすぐに死んでしまいます。結果として得られるオブジェクトの一部は、メモリ内に保持する必要があります (若いヒープから転送されます)。この操作中、これらのオブジェクトはすべてメモリ内にある必要があります。操作後、若いヒープ内のすべてのオブジェクトが正常に要求されていることがわかります。したがって、メモリリークはありません。

ヒープサイズが 3G に達すると、同じ操作がスムーズに実行されます。これは、必要な余分な時間がメモリの取得に費やされていることを明確に示しています。

このSun JDK 5.

4

4 に答える 4

3

私が間違っていなければ、Java は OS からメモリの予約を取得しようとします。したがって、Xms として 3 GB を要求すると、Java は OS に、これが利用可能であるがすぐにすべてのメモリで開始しないかどうかを尋ねます...それを予約する (割り当てない) ことさえあります。しかし、これらは詳細です。

通常、JVM は、重大な古い世代のガベージ コレクションを開始する前に、Xms サイズまで実行されます。若い世代の GC は常に実行されます。通常、GC は古い世代の GC が実行されていて、VM が Xms と Xmx の間にある場合、または同じ値に設定した場合はほぼ Xmx に到達した場合にのみ顕著になります。

短期間のオブジェクトに多くのメモリが必要な場合は、若い領域を次のように設定してメモリ領域を増やします... 1 GB -XX:NewSize=1gとしましょう。 「古い世代に。まだ実際のゴミになっていない場合、JVM はゴミをチェックし、ゴミを見つけず、サバイバー スペース間でコピーし、最後に古い世代に移動します。だから、若い世代のゴミのチェックを抑えてみてください。何も持っていないことがわかっている場合は、これを何とか延期してください...

試してみる!

于 2009-05-26T21:56:02.577 に答える
2

あなたの問題は、あなたが考えているところから来ているのではないと私は信じています。

最もコストがかかるのは GC サイクルであり、ヒープ サイズの割り当てではないようです。実際に多くのオブジェクトを作成および削除している場合。

プロファイリングに力を入れて、コストがかかっているものを正確に見つけ出し、それをリファクタリングする必要があります。

私の予感 - オブジェクトの作成と削除、および GC サイクル。

いずれにせよ、-Xms最小ヒープ サイズを設定する必要があります ( Sun でない場合は、JVM で確認してください)。そうではないと思う理由を正確に再確認してください。

于 2009-05-14T08:39:22.927 に答える
0

なぜヒープ割り当てが正しくないと思いますか? 400m しか表示されないオペレーティング システム ツールを使用しても、割り当てられていないわけではありません。

私はあなたが何を求めているのか本当に分かりません。400m 以上はすでに問題になっていますか、それともあなたのプログラムはそれだけの量を必要としているのでしょうか? 本当に大量のメモリを処理する必要があり、多くのオブジェクトが必要と思われる場合は、いくつかのことを実行できます。

メモリ消費量が直感と一致しない場合は、おそらくメモリ リークしているよりも適切な量です。それが、時間の経過とともに「遅くなる」理由を説明します。1 つの構造からオブジェクトを削除するのを忘れて、ガベージ コレクションが行われず、ルックアップなどの速度が低下している可能性があります。

あなたのメモリ設定自体が問題かもしれません。ガベージ コレクション自体は実行されません。何らかのしきい値に達した場合にのみ呼び出されます。大きなヒープ設定を指定し、オペレーティング システムに十分なメモリがある場合、ガベージ コレクションはあまり実行されません。

あなたが言及した特徴は、多くのオブジェクトが作成され、すぐにそれらが再び削除されるシナリオです。そうでなければ、ガベージ コレクションは問題になりません (ある種の世代別 gc)。つまり、「若い」オブジェクトしかありません。オブジェクトが短期間だけ必要な場合は、オブジェクト プールの使用を検討してください。これにより、ガベージ コレクションがまったくなくなります。

コードに gc を実行するのに適したタイミングがあることがわかっている場合は、gc を手動で実行して何かが変わるかどうかを確認することを検討できます。これはあなたが必要とするものです

  Runtime r = Runtime.getRuntime();
  r.gc();

これはデバッグ目的のためだけです。ほとんどの場合、gc は優れた機能を果たしているため、自分で gc を呼び出す必要はありません。

于 2009-05-14T09:07:52.903 に答える
0

私は太陽の vm を使用し、最小セットを 14 ギガに設定して開始しました。xms と xmx の両方の値を同じ値に設定してみる必要があるかもしれません。

于 2009-05-14T09:06:12.580 に答える