JVMユーティリティパラメータ(四)メモリユーティリティ

4422 ワード

転載先:http://ifeve.com/useful-jvm-flags-part-4-heap-tuning/
理想的な場合、JavaプログラムはJVMのデフォルト設定を使ってもよく動作するので、一般的にはJVMパラメータを設定する必要はありません.しかし、いくつかの性能の問題(残念なことに、これらの問題はよく発生します)のため、いくつかの関連しているJVMパラメータの知識は私達の仕事の良いパートナーになります.この記事では、JVMメモリ管理に関するいくつかのパラメータを紹介します.これらのパラメータを知って理解することは、開発者や運営者にとって有用です.
すべての制定されたHot Spotメモリ管理とゴミ回収アルゴリズムは同じメモリ区分に基づいています.新生代(young generation)には新しく割り当てられたものと比較的若い対象が記憶されています.古い年代(old generation)には長寿の対象が保存されています.これ以外にも、パーペチュアル(permant generation)は、JVMライフサイクル全体に伴う対象、例えば、ロードされたオブジェクトのクラス定義またはStringオブジェクト内部Cacheを記憶している.次に、私達はメモリを積み重ねるのが新生代、古い年代と永久世代のこの経典の策略によって区分したのだと仮定します.しかし、他のいくつかのメモリ区分戦略も可能であり、一つの顕著な例は新しいG 1のゴミ回収器であり、それは新生代と古い世代の違いをぼかしている.また、現在の開発プロセスは、HotSpot JVMのバージョンでは、古い年代と永遠の世代を区別しないことを示しているようです.
-Xms and-Xmx(or:-XX:Initial HeappSize and-XX:MaxHeappSize)
-Xmsと-Xmxは最も人気のあるJVMパラメータと言えます.JVMの初期と最大のメモリサイズを指定することができます.一般に、これらの2つのパラメータの数値単位はByteであるが、同時に、速記符号を使用することもサポートされている.例えば、「k」または「K」は「kilo」、「m」または「M」は「mega」、「g」または「G」は「giga」を表す.例えば、次のコマンドは初期化ヒープメモリが128 Mで、最大ヒープメモリが2 Gで、「MyApp」というJavaアプリケーションを起動します.1java -Xms128m -Xmx2g MyApp実際の使用過程では、初期化ヒープメモリのサイズは通常、ヒープメモリサイズの下界と見なされる.しかし、JVMは運転時にメモリのサイズを動的に調整することができますので、理論的にはメモリの大きさが初期化ヒープメモリの大きさより小さいことが分かります.しかし、非常に低いメモリを使っても、私はこのような状況に遭遇したことがありません.このような行為は開発者とシステム管理者に便利になります.私たちは「-Xms」と「-Xmx」を同じ大きさに設定することで、固定サイズのヒープメモリを得ることができます.Xmsと-Xmxは実は-XX:Initial HeappSizeと-XX:MaxHeappSizeの略語です.この二つのパラメータを直接使用することもできます.それらの効果は同じです.1$ java -XX:InitialHeapSize=128m -XX:MaxHeapSize=2g MyApp注意したいのは、すべてのJVMの初期\最大のメモリサイズに関する出力は、それらの完全な名前を使用しています.「Initial Heappsize」と「Initial HeappSize」.だから、実行中のJVMのヒープメモリを調べたら、例えば-XX:+PrintCommandLine Flagsパラメータを使って、あるいはJMXで調べたら、「Initial HeappSize」と「Initial HeappSize」の標識ではなく、「Xms」と「Xmx」を探してください.
-XX:+HeapumpOnutOfMemoryError and-XX:HeappPath
Xmxに適切な大きさを設定できないとメモリオーバーフロー(OutOfMemoryError)のリスクに直面する可能性があります.これはJVMを使う時に直面する最も恐ろしい猛獣の一つかもしれません.もう一つのテーマについてのブログで述べたように、メモリが溢れ出す根本的な原因については、細かい位置付けが必要です.通常、分析ヒープメモリのスナップショット(Heap Dump)は良い位置決め手段であり、メモリオーバーが発生した時にメモリのスナップショットが発生しないと本当に大変です.特に、JVMが崩壊したり、エラーが発生したりした場合は、数時間、数日間の生産システムが正常に運行されています.
ラッキーなことに、私たちは設定できます. JVMにメモリオーバーフローが発生した時に自動的にメモリスナップショットを生成させます.このパラメータがあると、メモリオーバーの異常に直面しなければならない時には多くの時間が節約されます.デフォルトでは、ヒープメモリのスナップショットはJVMの起動ディレクトリの下に保存されます.名前はjava_です.pid.hprof のファイルにあります.-XX:HeappPath=を設定することによって、デフォルトのヒープメモリのスナップショットの生成経路を変更することもできます.
このすべてはよさそうですが、一つ覚えておきたいことがあります.ヒープメモリのスナップショットファイルは膨大な可能性があります.特にメモリオーバーエラーが発生した場合.したがって、私たちはヒープメモリのスナップショットの生成経路を十分なディスク空間がある場所に指定することを推奨します.
-XX:OOOOutOf MemoryError
メモリオーバーフローが発生した時には、管理者にEメールで通知したり、掃除を実行したりするような命令も実行できます.このパラメータは-XX:OOOutOfMemoryErrによって実行できます.このパラメータは一連のコマンドとそれらのパラメータを受け入れられます.ここでは、私たちはその詳細には入らないだろうが、その例を提供します.下記の例では、メモリオーバーフローエラーが発生した場合、私達はヒープメモリのスナップショットを/tmp/heappdump.hprofファイルに書き込み、JVMの実行ディレクトリでスクリプトcleanup.shを実行します.1$ java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -XX:OnOutOfMemoryError = "sh ~/cleanup.sh"  MyApp -XX:PermSize and-XX:MaxPermSize
永久世代はヒープメモリの中で一つの独立した領域であり、すべてのJVMローディングの種類の対象表現を含んでいます.アプリケーションを成功的に実行するためには、JVMは多くの種類をロードします.これは大量の第三者ライブラリに依存しています.これはより多くのライブラリに依存しています.そして、中からクラスを読み込む必要があります.私たちは-XX:PermSizeを使用できます. と-XX:MaxPermSizeはこの目的を達成します.ここで-XX:MaxPermSizeは、永久サイズの最大値を設定するために使用されます.-XX:PermSizeは、永久初期サイズを設定するために使用されます.以下は簡単な例です.1$ java -XX:PermSize=128m -XX:MaxPermSize=256m MyAppここで設定した永久サイズは使用パラメータ-XX:MaxHeappSizeに含まれません. セットされたヒープのメモリサイズにあります.つまり-XX:MaxPermSizeで設定した永久メモリはパラメータ-XX:MaxHeappSizeで設定されたヒープメモリ以外のメモリが必要になります.
-XX:Initial CodeCacheSize and-XX:ReservedCodeCacheSize
JVMは興味深いが、しばしば無視されるメモリ領域は「コードキャッシュ」であり、コンパイルされた方法で生成されたローカルコードを記憶するために使用される.コードキャッシュは確かに性能問題が少ないですが、その影響が発生すると壊滅的になる可能性があります.コードキャッシュがいっぱいになったら、JVMは警告メッセージを印刷して、interpreted-onlyモードに切り替えます.JITコンパイラは停止されます.バイトコードはマシンコードにコンパイルされなくなります.このため、アプリケーションは継続して実行しますが、実行速度は一桁低下します.他のメモリエリアのように、コードキャッシュのサイズをカスタマイズできます.関連するパラメータは-XX:Initial CodeCacheSizeと-XX:ReservedCodeCacheSizeで、それらのパラメータは上で紹介したパラメータと同じで、バイト値です.
-XX:+UseCodeCacheFushing
コードキャッシュが継続的に増加している場合、例えば熱配置によるメモリリークは、コードのキャッシュサイズを高めることによって、オーバーフローが発生するのを遅らせるだけです.このような状況の発生を避けるために、コードバッファが満たされている時に、JVMにいくつかのコンパイルコードを放棄させる面白い新しいパラメータを試してもいいです.-XX:+UseCodeCacheFushingというパラメータを使用することにより、コード・キャッシュが満たされると、JVMがinterpreted-onlyモードに切り替わることを少なくとも避けることができます.しかし、私はまだコードキャッシュの問題が発生した根本的な原因を早急に解決することを提案します.