はじめに
メモリ管理は常に JAVA 言語の誇りであり、JAVA プログラマは基本的にメモリ管理に関連する詳細を完全に無視してビジネス ロジックのみに集中できます。しかし、世の中に完璧なものはありません。利便性をもたらす一方で、多くの異常なメモリ オーバーフローやリークの問題も引き起こします。
恐ろしいのはそれだけではありません。他の言語で開発するプログラマの中には、JAVA プログラマを「メモリに無知」というレッテルを貼る人もいますが、これは本当に容認できません。結局のところ、JAVA には malloc も delete も、デストラクタも、ポインタもありません。JAVA を初めて使用するプログラマは、どのようにしてメモリ部分に触れることができるのでしょうか。さらに、多くの JAVA プログラマは、専攻を辞めて大学に戻った友人でもあります。中途半端な僧侶。
しかし、この事実は受け入れがたいものですが、実際にメモリについて何も知らない Java プログラマはたくさんいます。メモリ関連の知識を習得しても、日々の開発に劇的な変化やメリットがもたらされるわけではありませんが、それでも微妙に改善されます。メモリ管理を理解すると、これについても深く理解できると思います。
メモリ分割
メモリという言葉に関しては、プログラムが実行されているときにのみ存在するデータ格納領域です。この領域の分割については、各仮想マシンが独自の分割方法を持っていますが、それに従う必要があります。 JAVA仮想化によりマシンの基本仕様が実装されます。
仮想マシンの仕様では、メモリは 6 つの部分、つまり PC レジスタ、JAVA 仮想マシン スタック、JAVA ヒープ、メソッド領域、ランタイム定数プール、およびローカル メソッド スタックに分割されます。
JAVA 仮想マシン仕様と JAVA 仮想マシン
ここでは、JAVA 仮想マシン仕様と JAVA 仮想マシンの違いについても説明する必要があります。名前が示すように、JAVA 仮想マシン仕様は、JAVA 仮想マシン仕様を実装するための標準要件です。 JAVA 仮想マシンは Oracle によって策定されており、私たちが通常話している JAVA 仮想マシンは、一般に特定の JAVA 仮想マシン仕様の実装を指します。たとえば、最も一般的に使用される JAVA 仮想マシンのホットスポットは、実際には、JAVA 仮想マシンの仕様を深く理解しており、それに興味がある場合でも、独自の実装を作成できます。もちろん、JAVA 仮想マシンの難しさは想像に難くありません。
構造図
次の図は、Baidu Wenku から引用した JVM 構造図です。実行時定数プールはメソッド領域によって割り当てられる領域であるため、この図には実行時定数プールはありません。
メモリ領域の詳細説明
上の図では、メモリとは長方形のボックス内の実行時データ領域を指します。各部の機能を簡単に紹介します。
1. PC レジスタ (スレッド固有)。 ): 完全な名前はプログラム カウント レジスタで、各スレッドによって現在実行されている JAVA メソッドのアドレスを記録します。ローカル メソッドが現在実行されている場合、プログラム カウンターは空のアドレスになります。その機能は、マルチスレッドと、スレッドのブロック、回復、一時停止などの一連の操作をサポートすることで、各スレッドの現在の実行位置を覚えていない場合に回復方法を直感的に想像できます。これに基づいて、各スレッドには PC レジスタがあり、PC レジスタはスレッドに固有であることを意味します。
2. JAVA 仮想マシン スタック (スレッドに固有): JAVA 仮想マシン スタックはスレッドの作成時に作成され、スタック フレームを保存するために使用されます。
スタックフレーム: 簡単に言うと、メソッドの実行時に一時的なデータを保存する領域として解釈でき、データと処理結果の一部が含まれます。処理メソッド、戻り値、動的リンク、および例外ディスパッチされたタスク。スタック フレームはメソッドの作成時に作成され、メソッドが例外をスローした場合もメソッドの終了とみなされます。ただし、各スタック フレームには、独自のローカル変数テーブルとオペランド スタック、および現在のクラスのランタイム定数プールへの参照があります。
ローカル変数テーブル: メソッドのローカル変数のリストであり、コンパイル中にクラスファイルに書き込まれます。分かりやすく説明すると、インデックス 0 から長さ 1 までの各ローカル変数に対応するオブジェクト配列、特にインスタンス メソッドのローカル変数テーブルの場合、0 番目のローカル変数と考えることができます。 be 現在のインスタンスへの参照 (this キーワード)、残りのローカル変数はインデックス 1 から始まります。
演算子スタック: これは後入れ先出し (LIFO) スタックであり、その長さもコンパイル中にクラス ファイルに書き込まれて固定されます。その機能は、バイトコード命令の演算変数計算のためのスペースを提供することです。たとえば、単に int a=9 という文の場合、最初に 9 をオペランド スタックにプッシュし、次に 9 を変数 a に割り当てる必要があります。
3. JAVA ヒープ (グローバル共有): この部分が JAVA メモリの最も重要な部分である理由は、その重要性のためではなく、開発者が最も負担する必要がある部分を指すためです。に注意してください。これは、JAVA 仮想マシンの起動時に作成され、すべてのオブジェクト インスタンスと配列オブジェクトを保存し、ガベージ コレクター (GC) とよく呼ばれる「自動メモリ管理システム」が組み込まれています。 JAVA ヒープ内のメモリの解放は開発者によって制御されず、JAVA 仮想マシンによって完全に処理されます。 JAVA 仮想マシンの仕様には、JAVA 仮想マシンにガベージ コレクタを実装する方法に関する明確な規定がありません。このため、私たちが通常使用する JAVA 仮想マシンには、さまざまなアルゴリズムと実装方法を使用するさまざまな種類のガベージ コレクタが提供されています。さまざまなパフォーマンスニーズ。
4. メソッド領域 (グローバル共有): メソッド領域もヒープのコンポーネントであり、主に実行時定数プール、フィールド情報、メソッド情報、構築メソッドと通常の関数のバイトコード内容、およびいくつかの特殊なメソッドが格納されます。 JAVA ヒープとの最大の違いは、格納される情報が JAVA ヒープとは異なることです。最大の違いは、JAVA 仮想マシン仕様のこの部分では自動メモリ管理システム (GC) の実装が義務付けられていないことです。
5. ネイティブ メソッド スタック (スレッドに固有): ローカル メソッド スタックは、ネイティブ メソッドの実行をサポートするために使用される従来のスタックです。 JAVA 仮想マシンが他の言語を使用して命令セット インタプリタを実装する場合、ローカル メソッド スタックも使用されます。前の 2 つのどちらも発生しない場合、つまり、JAVA 仮想マシンがネイティブ メソッド スタックに依存しておらず、JAVA 仮想マシンがネイティブ メソッドをサポートしていない場合、ネイティブ メソッド スタックは必要ありません。必要に応じて、各スレッドの起動時にローカル メソッド スタックも作成されます。
PC レジスタを除いて、上記の他の 4 つのメモリ領域は通常、お客様にサイズ調整パラメータを提供するために JAVA 仮想マシンの実装を必要とします。これらのパラメータは、当社がよく使用する Xms、Xmx などです。
メモリ管理
メモリ管理は、メモリの割り当てとメモリの解放に分かれています。上記の 5 つのメモリ領域を見ると、実際には大きく 2 つの部分に分けられ、1 つはグローバルに共有され、もう 1 つはスレッドに固有です。
スレッドに固有のメモリのこの部分は、スレッドの開始時に作成され、スレッドが破棄されるとメモリが解放されます。メモリのこの部分はガベージ コレクターによって管理される必要はありませんが、スレッドが作成されるたびに、JAVA 仮想マシンによって対応する PC レジスタと JAVA 仮想マシン スタックが割り当てられます。必要な場合は、ローカル メソッド スタックも存在します。同様に、スレッドが破棄されると、JAVA 仮想マシンは、このスレッドによって占有されていたすべてのメモリも解放します。
スレッドに固有のメモリの部分と比較して、グローバル共有メモリの部分は処理がより困難ですが、メモリのこの部分は自動メモリ管理システム (GC) を実装する必要があるため、これは仮想マシンの実装にのみ当てはまります。 。
グローバル共有メモリのこの部分 (以下、ヒープと呼びます) へのメモリ割り当ては、主にプログラマが new キーワードを明示的に使用することによってトリガーされます。新しいメモリのこの部分をどこにどのように割り当てるかについては、JAVA 仮想によって決定されます。機械。 。この部分のメモリの解放は、自動メモリ管理システム (以下、GC と呼びます) によって管理されます。
通常、ヒープ メモリの割り当ては GC 戦略と実装に依存します。割り当ての際には、メモリのこの部分を再利用する方法を考慮する必要があります。このため、メモリ割り当ての説明では、メモリがどのように割り当てられるかをよりよく理解するために、まずメモリがどのようにリサイクルされるかを理解する必要があります。
結論
上記は、JVM メモリ管理の内容です --JAVA 言語メモリ管理の概要 詳細については、PHP 中国語 Web サイト (www.php.cn) に注目してください。