私はclojureアプリケーションを開発していますが、必要以上に多くのメモリを使用しているようです。メモリリークだと思いましたが、jvisualvmで調べたところ、GCが十分に実行されていないようです。赤い輪郭は、手動でGCを呼び出した場所です。30mb前後を使用しているように見えるのに、なぜ300mbを割り当てるのですか?
私はclojureアプリケーションを開発していますが、必要以上に多くのメモリを使用しているようです。メモリリークだと思いましたが、jvisualvmで調べたところ、GCが十分に実行されていないようです。赤い輪郭は、手動でGCを呼び出した場所です。30mb前後を使用しているように見えるのに、なぜ300mbを割り当てるのですか?
ヒープが大きすぎると思われる場合は、ヒープを小さくしてください。GCは必要な場合にのみ実行されます。
(コントロールは何年にもわたって変更されていますが、初期ヒープサイズ、増分サイズ、および最大サイズに関してはまだ変更されていると思います。初期ヒープサイズが小さい場合は、ない限り小さいままになります。ヒープ使用量の「最高水準点」は、それを押し上げます。)
JVMには、最初に割り当てられた量や割り当てる最大量など、メモリ管理を調整するパラメータがあります。これらのパラメータ以外に、JVMには、使用するのに妥当な量のメモリと見なされるものを知る方法がありません。私の知る限り、JVMが特定のスケジュールでGCを実行する必要はなく、Javaの定義の対象となるメモリ使用量もありません。
たとえば、JVMで使用可能な最大メモリが100 MBであり、現在、デッドオブジェクトを含めて50MBを使用しているとします。1MBを必要とするNEWがあります。JVMはGCを実行する必要がありますか?それは必須ではありません。最大値に達する前に十分なスペースがあります。それは良い考えですか?それを言うのは非常に難しいです。大量のメモリを使用するのか、大量のGCを実行するのか、どちらが悪いですか?
Javaプログラマーとして、あなたは通常、知ったり気にしたりするべきではありません。あなたがメモリ不足であると宣言する前にGCを実行する限り、それはどのような違いをもたらしますか?アプリが大量のメモリを使用しているために他のアプリが必要なものを割り当てることができない場合は、実行時パラメーターを変更して、使用する最大値を減らしてください。それが重要なことの限界であるべきです。
JVMは世代別ガベージコレクターを使用します。通常、常に最大30MBのデータが存在する場合は、新世代のサイズを60MBなどに設定する必要があります。そうすれば、ガベージコレクターは、古い世代に昇格する前に、前のパスからすべてのものを収集する必要があります(収集される頻度ははるかに低くなります)。
Sun /OracleJVMには多数のパフォーマンス調整オプションがあります。あなたはおそらく-XX:NewSize=60m
これを設定したいと思うでしょう。
どのオプションを設定するかについて間違っている可能性があります。この問題により適したオプションがある可能性があります。ただし、他の回答で提案されているように、ヒープの合計サイズを単純に削減するよりも、これらのGCフラグを調整する方がはるかに優れたオプションだと思います。
更新:世代固有のヒープサイズの設定のトピックで私が見つけたいくつかの詳細情報は次のとおりです。