概要:
Java仮想マシンが起動すると、ヒープメモリとメソッド領域が作成されます
メソッド領域には、主に、仮想マシンによってロードされたクラス情報、定数、静的変数などの共有情報が格納されます。
スレッドが生成されると、仮想マシンは仮想マシンスタック、ローカルメソッドスタック、カウンターを作成し、それをスレッドに割り当てます。スレッドがメソッドを実行すると、スタックフレームが生成されます。メソッドのローカル変数とパラメーター(基本データ)タイプと参照タイプ)はスタックフレームに格納され、このメソッドのオブジェクトインスタンスと配列インスタンスの情報はヒープメモリに格納されます
メソッドに入ると、前のスタックフレームがスタックにプッシュされ、新しいメソッドがスタックの一番上に配置されます。新しいメソッドを実行した後、スタックフレームの戻りアドレスに従って前のメソッドの実行コードセグメントが見つかり、スタックがポップされます。
このスレッドの実行が完了すると、それに応じてスタックが破棄されます
JVMメモリー領域は、ヒープ、メソッド領域、仮想マシンスタック、ローカルメソッドスタック、プログラムカウンターの5つの部分に分かれています。
プログラムカウンター(PCレジスタ)スレッドプライベート
プログラムカウンタは、現在のスレッドによって実行されたバイトコードを記録する行番号インジケータです。マルチスレッドの同時処理時に、CPUはコンテキストの切り替え後に完了したログをCPUに通知し、操作の繰り返しを回避します。
仮想マシンスタックスレッドプライベート
仮想マシンスタックは、仮想マシンメモリ内のメモリ領域であり、スレッド専用です。スタックフレームを格納するために使用されます。スタックフレームはメソッドに対応しますスタックフレームのポップとプッシュは、メソッドの終わりと呼び出しの始まりに対応します。-Xss は、各スレッドのスタックサイズを設定することを意味します。JDK1.5より前のデフォルトのスタックサイズは256Kで、その後のデフォルトサイズは1Mでした。
スタックフレーム : 完全なスタックフレームには、次の情報が含まれます。
ローカル変数テーブル オペランドスタック スタックフレーム情報
ローカル変数テーブル----スタックローカル変数テーブルには、メソッドパラメータとローカル変数が格納されますこれらのエントリは、基本タイプのデータと参照データタイプにすることができます
オペランドスタックオペランドスタックは、Java仮想マシンスタックでの計算に使用される一時的なデータストレージ領域として理解でき、結果はスタックにプッシュされ、ローカル変数テーブルにポップアップされます。
スタックフレーム情報スタックフレーム情報には、メソッド自体のエントリアドレス、メソッドの戻りアドレス、デバッグ情報またはその他の追加情報が含まれます。
例外があります:
-
StackOverflowError :
- JVMは各スレッドの仮想マシンスタックに特定のメモリサイズを割り当てます------> -Xssパラメータ
したがって、仮想マシンスタックが保持できるスタックフレームの数は制限されます。スタックフレームがスタックにプッシュされ続けているが、スタックから外れていない場合、現在のスレッド仮想マシンスタックのメモリ領域が最終的に使い果たされ、例外がスローされます。
-
OutOfMemoryError(OOM) :
- スタックを拡張するときに仮想マシンが十分なメモリを適用できない場合、OutOfMemmoryError例外がスローされます
ネイティブスタックスレッドプライベート
仮想マシンスタックと同様に、スレッドアイソレーションの特性があり、StackOverflowErrorおよびOutOfMemoryError例外をスローできます。ローカルメソッドスタックによって提供されるオブジェクトは、JVMによって実行されるネイティブメソッドですが、仮想マシンスタックは、JVMによって実行されるjavaメソッドを提供します
Javaヒープ(ヘッド)スレッド共有
Javaヒープは、仮想マシンの起動時に作成される、すべてのスレッドで共有されるメモリ領域ですこのメモリ領域の唯一の目的は、オブジェクトインスタンスを格納することです。ほとんどすべてのオブジェクトインスタンスは、ここでメモリを割り当てます
JVMメモリは、ヒープメモリと非ヒープメモリに分けられます。ヒープメモリ:(1/3)若い世代:|| ===(8/10)エデン|| ===(2/10)サバイバーエリア|| ===(1/10)FromSpace|| ===(1/10)ToSpace(2/3)旧世代非ヒープメモリ:永久生成(Permanent Generation)ヒープメモリ:オブジェクトが格納され、ガベージコレクターがこれらのオブジェクトを収集し、GCアルゴリズムに従ってそれらをリサイクルします。非ヒープメモリ:永続的な世代は、メソッド領域とも呼ばれ、クラスメタデータ、メソッド、定数、属性などの長期間存続するオブジェクトを格納します。若い世代(新):若い世代は、JVMによって割り当てられたばかりのJavaオブジェクトを格納するために使用されますTenured(Tenured):若い世代でガベージコレクションによって収集されないオブジェクトは、古い世代にコピーされます永続的な世代(パーマ):クラスとメソッドのメタ情報を永続的に保存します。そのサイズは、プロジェクトの規模、クラスの量、およびメソッドに関連します。通常、128Mで十分です。設定の原則は、スペースの30%を予約することです。
備考:JDK1.8バージョンは、MetaSpace(MetaSpace )ではなく、永続的な世代を廃止しましたメタスペースは永続的な生成に似ており、どちらもメソッド領域の実現ですそれらの間の最大の違いは次のとおりです。メタスペースはJVMにありませんが、ローカルメモリを使用しますメタスペースには2つのパラメーターがあります。MetaspaceSize:メタスペースのサイズを初期化し、GCしきい値を制御しますMaxMetaspaceSize:メタスペースサイズの上限を制限して、異常に多くの物理メモリを占有しないようにします。
メソッドエリア
メソッド領域は「永続的な生成」とも呼ばれますこれは、仮想マシンによってロードされたクラス情報、定数、および静的変数を格納するために使用され、各スレッドによって共有されるメモリ領域ですJDK8より前のHotSpot JVMでは、これらの「永続的な」領域は「永続的な生成」と呼ばれますPermanent Generationは、コマンドラインでパラメーターを設定することにより、JVMが起動する前の連続したヒープスペースです。-XX:MaxPermSize は、最大割り当て可能メモリスペース、デフォルトサイズは64M(64ビットJVMデフォルトは85M)JDK8以降、JVMには永続的な世代(PermGen)がなくなりましたしかし、クラスメタデータ情報(メタデータ)はまだ存在していますが、連続ヒープスペースには格納されず、「メタスペース」(ネイティブメモリ)と呼ばれるローカルメモリに移動されます。
メソッド領域または不滅生成に関連する設定-XX:PermSize = 64MB最小サイズ、初期割り当て-XX:MaxPermSize = 256MB必要に応じて割り当てられる最大許容割り当てサイズごみをリサイクルせずにセット-XX:+ CMSClassUnloadingEnabled-XX:+ CMSPermGenSweepingEnabledデフォルトのサイズ-serverオプションのデフォルトのMaxPermSizeは64mです。-clientオプションのデフォルトのMaxPermSizeは32mです。
JVMメモリパラメータ設定
-Xms ——————————ヒープの最小スペースサイズを設定します
-Xmx ——————————ヒープの最大スペースサイズを設定します
-Xmn ——————————若い世代のサイズを設定します
-XX:NewSize ——————————新しい世代の最小スペースサイズを設定します
-XX:MaxNewSize ——————————新しい世代の最大スペースサイズを設定します
-XX:PermSize ——————————永続的な世代の最小スペースサイズを設定します
-XX:MaxPermSize ——————————永続的な世代の最大スペースサイズを設定します
-Xss ——————————各スレッドのスタックサイズを設定します
-XX:+ UseParallelGC ————————ガベージコレクターを並列コレクターとして選択します
この構成は若い世代にのみ有効です。つまり、上記の構成では、若い世代は並行収集を使用しますが、古い世代は引き続きシリアル収集を使用します。
-XX:ParallelGCThreads = 20 ——————————並列コレクタのスレッド数を構成します-つまり、同時にガベージコレクションされるスレッドの数。
典型的なJVMパラメータ設定リファレンス:
java-Xmx3550m-Xms3550m-Xmn2g-Xss128k
-XX:ParallelGCThreads = 20
-XX:+ UseConcMarkSweepGC
-XX:+ UseParNewGC
分析:
-Xmx3550m:
JVMの最大利用可能メモリを3550Mに設定します
-Xms3550m:
JVM初期メモリを3550mに設定します
この値を-Xmxと同じように設定して、各ガベージコレクションの完了後にJVMがメモリを再割り当てしないようにすることができます。
-Xmn2g:
若い世代のサイズを2Gに設定します。
ヒープ全体のサイズ=若い世代のサイズ+古い世代のサイズ+永続的な世代のサイズ
永続的な世代のサイズは通常64mに固定されているため、若い世代を増やすと、古い世代のサイズが小さくなります
-Xss128k:
各スレッドのスタックサイズを設定します。
JDK5.0以降、各スレッドのスタックサイズは1Mになり、以前は各スレッドのスタックサイズは256Kになりました。
アプリケーションのスレッドが必要とするメモリサイズに応じて調整できます。同じ物理メモリでこの値を減らすと、より多くのスレッドを生成できます
ただし、オペレーティングシステムにはプロセス内のスレッド数に制限があり、無制限に生成することはできません。エクスペリエンス値は3000〜5000です。