Java JVMの詳細:
JVMに関する関連知識
1。ヒープとスタックメモリ
1. JVMのスタックメモリは、主に基本的なタイプの変数とオブジェクトへの参照を保存します。
2. JVMのヒープメモリは、主に新しい、可変長文字列(StringBuilderとStringBuffered)で作成されたオブジェクトと配列を保存します。
ヒープを使用する利点は、より柔軟なストレージスペースが動的に割り当てられたストレージスペースであることですが、不利な点は、メモリを動的に割り当てるのが遅いことです。スタックの使用はより速く、データ共有を達成できますが、不利な点は、スタックのデータサイズと寿命を決定し、柔軟性を欠く必要があることです
3.静的ストレージ割り当ては、静的変数と静的コードブロックを保存するために使用されます。
2。JVMの理解
JVMはJava仮想マシンです。特定のオペレーティングシステムプラットフォームに関連する情報をブロックするため、JavaプログラムはJava仮想マシンで実行されているオブジェクトコード(BYTEコード)のみを生成し、クロスプラットフォーム操作を実現できます。
その原則は次のとおりです。Javaソースファイルは、Javaコンパイラを介してByteCodeプログラムにコンパイルされ、各命令はJVMを介して異なるプラットフォームのマシンコードに翻訳され、特定のプラットフォームを介して実行されます。
JVMのメモリ領域は、主にメソッド領域、JVMスタック、ヒープ、ローカルメソッドスタック、プログラムカウンターに分かれています
プログラムカウンター:現在実行されている命令を記録するために使用されます。これはOOMのない唯一の領域です。
JVMスタック:スレッドはプライベートです。各スレッドは、同時にJVMスタックを作成します。現在のスレッドにローカルの基本変数、部分的な返品結果、スタックフレーム、およびオブジェクト参照アドレスを保存します。
ヒープ:いくつかのオブジェクトと配列を保存するために使用されるスレッド共有。共有されるため、ロックが必要であり、オーバーヘッドが高くなります。
メソッド領域:このメソッド領域は、クラスの情報(名前、修飾子など)を保存する永続的な生成に対応し、クラスの静的変数、クラスで定義された定数など。
ローカルメソッドスタック:ネイティブメソッドの実行をサポートし、各ネイティブメソッドの呼び出しステータスを保存するために使用されます。
Java Garbage Collectionは主にヒープとメソッドの領域に焦点を当てています。ヒープは新世代と古い世代に分割され、一般的に新しくなったオブジェクトは新世代に配置されます。そして、新世代はエデン地域と2つの生存地域に分かれています。
ガベージコレクションのメカニズムは次のとおりです。最初に、どのオブジェクトがゴミであるか、つまり使用されなくなったかを決定し、次に、対応するアルゴリズム(マーククリアリングアルゴリズム、コピー、マーク締めアルゴリズム、ジェネレーションコレクションアルゴリズム)を使用して、ゴミを収集します。
1。マーククリアリングアルゴリズム:
マーキングステージとクリアリングステージの2つの段階に分かれています。まず、リサイクルする必要があるオブジェクトをマークし、次にマーキングオブジェクトが占めるスペースをリサイクルします。
その実装は比較的簡単ですが、その欠点は、メモリフラグメントを簡単に生成でき、将来的に大きなオブジェクトにスペースを割り当てるときに十分なメモリを見つけることができなくなり、事前に新しいガベージコレクションアクションをトリガーすることができないことです。
2。コピーアルゴリズム:
マーククリーニングアルゴリズムの欠点を解決するために、コピーアルゴリズムは容量に応じてメモリを同じサイズの2つの領域に分割し、そのうちの1つだけが一度に使用されます。 1つのピースが使い果たされると、まだ生存するオブジェクトが別の領域にコピーされ、使用済みの領域がクリーンアップされるため、断片化は容易ではありません。
メモリの断片化の問題は解決されますが、不利な点は、使用されるメモリが元の半分に減少し、コピー効率が生存するオブジェクトの数に関連していることです。数が大きい場合、効率は大幅に低下します。
3。マーキング - 組織化アルゴリズム
コピーアルゴリズムの欠陥を解くために、マークタイディアルゴリズムが生まれ、マーキング段階もマーククリーニングアルゴリズムのようでした。第一に、リサイクルする必要があるオブジェクトはマークされていますが、それらを直接リサイクルするのではなく、すべての生き残ったオブジェクトを反対側に移動し、境界の外側のメモリをクリーンアップします。
4。世代コレクションアルゴリズム
これは現在最も一般的に使用されているアルゴリズムです。その核となるアイデアは、オブジェクトのサバイバルサイクルに応じて、メモリをいくつかの異なる領域に分割することです。一般的に、ヒープ領域は新世代と古い世代に分かれています。古い世代の特徴は、ガベージが収集されるたびにリサイクルする必要があるオブジェクトが少ないことですが、新世代が多いため、異なるアルゴリズムが採用されます。
現在、新世代のほとんどはコピーアルゴリズムを使用していますが、実際、新世代は1:1の比率に分割されていません。一般的に言えば、新世代はより大きなエデン空間と2つの小さな生存空間に分かれています。エデンスペースとサバイバースペースの1つが使用されるたびに、リサイクルすると、エデンとサバイバーのまだ生存するオブジェクトが別の生存者スペースにコピーされ、エデンと使用された生存空間が掃除されます。
老年は毎回少数のオブジェクトのみがリサイクルされることであるため、マークコンパクトアルゴリズムが一般的に使用されます。
ヒープ領域の外側には、クラスクラス、定数、メソッドの説明などを保存するために使用される永続的な生成である別の世代があることに注意してください。永続的な生成のリサイクルは、主に廃棄された定数と役に立たないクラスの2つの部分をリサイクルします。
では、どのオブジェクトが「ごみ」であるかをどのように判断しますか?
方法1。参照カウント方法:
Javaでは、参照を介してオブジェクトに関連付けられています。つまり、オブジェクトを操作する場合は、参照を使用して行う必要があります。その後、簡単な方法は、参照カウントによってオブジェクトをリサイクルできるかどうかを判断することであることは明らかです。一般性を失うことなく、オブジェクトに関連する参照がない場合、オブジェクトが基本的に他の場所で使用される可能性が低く、オブジェクトがリサイクル可能なオブジェクトになることを意味します。この方法は、参照カウント方法になります。
利点:単純な実装と高効率
短所:円形の参照の問題を解決できません
方法2。アクセシビリティ分析方法:
この方法の基本的なアイデアは、一連の「GCルーツ」オブジェクトを出発点として検索することです。 「GC Roots」とオブジェクトの間にアクセス可能なパスがない場合、オブジェクトは到達不能と言われます。ただし、到達不能であると判断されたオブジェクトは、必ずしもリサイクル可能なオブジェクトになるとは限らないことに注意する必要があります。到達不能と判断されるオブジェクトは、リサイクル可能なオブジェクトになるために、少なくとも2つのマーキングプロセスを通過する必要があります。これら2つのマーキングプロセス中にリサイクル可能なオブジェクトになる可能性がまだない場合、それは基本的にリサイクル可能なオブジェクトになります。
どのオブジェクトがGCルーツになりますか?
1。JVMスタックで参照されているオブジェクト(スタックフレームのローカル変数テーブル)。
2。メソッド領域のクラス静的属性によって参照されるオブジェクト。
3。メソッド領域の定数によって参照されるオブジェクト
4。ローカルメソッドスタックのJNI(つまり、一般的なネイティブ方法)によって参照されるオブジェクト。
プログラマーの場合、いくつかの方法でGCオーバーヘッドを減らすこともできます。
1。System.gc()メソッドを表示しないでください
2。一時的なオブジェクトの使用を最小限に抑えます
3.オブジェクトが使用されていない場合、表示設定はnullに設定されます
4。弦の蓄積された文字列の代わりに、弦楽剤を使用してみてください
5.基本タイプの変数(int long)を使用できる場合は、オブジェクト(整数、長い)を使用しないでください
6.静的オブジェクト変数をできるだけ使用しません
読んでくれてありがとう、私はそれがあなたを助けることができることを願っています。このサイトへのご支援ありがとうございます!