Java では、メモリ管理はオブジェクトの割り当てと割り当て解除のプロセスであり、メモリ管理と呼ばれます。 Java はメモリ管理を自動的に行います。 Java は、と呼ばれる自動メモリ管理システムを使用します。 ガベージコレクター 。したがって、アプリケーションにメモリ管理ロジックを実装する必要はありません。 Java メモリ管理は、次の 2 つの主要な部分に分かれています。
JVMのメモリ構造
JVM はヒープ内にさまざまな実行時データ領域を作成します。これらの領域はプログラム実行時に使用されます。メモリ領域は JVM の終了時に破棄されますが、データ領域はスレッドの終了時に破棄されます。
メソッドエリア
メソッド領域は、すべてのスレッド間で共有されるヒープ メモリの一部です。 JVM の起動時に作成されます。これは、クラス構造、スーパークラス名、インターフェイス名、およびコンストラクターを保存するために使用されます。 JVM は、次の種類の情報をメソッド領域に保存します。
トーチの取り付け
- 型の完全修飾名 (例: String)
- 型の修飾子
- 型の直接のスーパークラス名
- スーパー インターフェイスの完全修飾名の構造化されたリスト。
ヒープ領域
ヒープには実際のオブジェクトが格納されます。 JVM の起動時に作成されます。ユーザーは必要に応じてヒープを制御できます。固定サイズまたは動的サイズにすることができます。新しいキーワードを使用すると、JVM はヒープ内にオブジェクトのインスタンスを作成します。そのオブジェクトの参照はスタックに保存されます。実行中の JVM プロセスごとにヒープが 1 つだけ存在します。ヒープがいっぱいになると、ガベージが収集されます。例えば:
StringBuilder sb= new StringBuilder();
上記のステートメントは、StringBuilder クラスのオブジェクトを作成します。オブジェクトはヒープに割り当てられ、参照 sb はスタックに割り当てられます。ヒープは次の部分に分割されます。
- 若い世代
- 生存者スペース
- 旧世代
- 永久世代
- コードキャッシュ
参照タイプ
参照には 4 つのタイプがあります。 強い 、 弱い 、 柔らかい 、 そして ファントムリファレンス 。参照の種類の違いは、それらが参照するヒープ上のオブジェクトが、異なる基準に基づいてガベージ コレクションの対象となるかどうかです。
強力な参照: 日常のプログラミングで使用するため、非常に簡単です。強参照がアタッチされているオブジェクトはガベージ コレクションの対象になりません。次のステートメントを使用して、強参照を作成できます。
StringBuilder sb= new StringBuilder();
弱い参照: 次のガベージ コレクション プロセスの後は存続しません。データがいつ再度リクエストされるかわからない場合。この状態では、それへの弱い参照を作成できます。場合によっては、ガベージ コレクターが処理すると、オブジェクトが破棄されます。そのオブジェクトを再度取得しようとすると、null 値が返されます。で定義されています java.lang.ref.WeakReference クラス。次のステートメントを使用して弱い参照を作成できます。
WeakReference reference = new WeakReference(new StringBuilder());
ソフトリファレンス: アプリケーションのメモリが不足しているときに収集されます。ガベージ コレクターは、ソフトに到達可能なオブジェクトを収集しません。すべてのソフト参照オブジェクトは、OutOfMemoryError がスローされる前に収集されます。次のステートメントを使用してソフト参照を作成できます。
SoftReference reference = new SoftReference(new StringBuilder());
ファントムリファレンス: で利用可能です java.lang.ref パッケージ。で定義されています java.lang.ref.PhantomReference クラス。それらを指すファントム参照のみを持つオブジェクトは、ガベージ コレクターが収集したいときにいつでも収集できます。次のステートメントを使用してファントム参照を作成できます。
PhantomReference reference = new PhantomReference(new StringBuilder());
スタックエリア
スタック領域はスレッド作成時に生成されます。固定サイズまたは動的サイズのいずれかにすることができます。スタック メモリはスレッドごとに割り当てられます。データと部分的な結果を保存するために使用されます。ヒープ オブジェクトへの参照が含まれています。また、ヒープからのオブジェクトへの参照ではなく、値自体も保持します。スタックに格納される変数には、スコープと呼ばれる特定の可視性があります。
分数として .04
スタックフレーム: スタック フレームは、スレッドのデータを含むデータ構造です。スレッド データは、現在のメソッドのスレッドの状態を表します。
- 部分的な結果とデータを保存するために使用されます。また、動的リンク、メソッドによって返される値、および例外のディスパッチも実行されます。
- メソッドが呼び出されると、新しいフレームが作成されます。メソッドの呼び出しが完了すると、フレームが破棄されます。
- 各フレームには、独自のローカル変数配列 (LVA)、オペランド スタック (OS)、およびフレーム データ (FD) が含まれています。
- LVA、OS、FD のサイズはコンパイル時に決定されます。
- 特定の制御スレッド内の任意の時点でアクティブになるフレームは 1 つだけ (メソッドを実行するフレーム) です。このフレームは現在のフレームと呼ばれ、そのメソッドは現在のメソッドとして知られています。メソッドのクラスは現在のクラスと呼ばれます。
- フレームは、そのメソッドが別のメソッドを呼び出す場合、またはメソッドが完了した場合に、現在のメソッドを停止します。
- スレッドによって作成されたフレームはそのスレッドに対してローカルであり、他のスレッドから参照することはできません。
ネイティブメソッドスタック
C スタックとも呼ばれます。 Java 以外の言語で書かれたネイティブ コードのスタックです。 Java Native Interface (JNI) はネイティブ スタックを呼び出します。ネイティブ スタックのパフォーマンスは OS に依存します。
PCレジスタ
各スレッドには、プログラム カウンター (PC) レジスタが関連付けられています。 PC レジスタにはリターン アドレスまたはネイティブ ポインタが格納されます。また、現在実行されている JVM 命令のアドレスも含まれます。
ガベージコレクターの働き
ガベージ コレクターの概要
Java でプログラムを実行すると、さまざまな方法でメモリが使用されます。ヒープは、オブジェクトが存在するメモリの一部です。これは、ガベージ コレクション プロセスに関与するメモリの唯一の部分です。ガベージ コレクション ヒープとも呼ばれます。すべてのガベージ コレクションにより、ヒープにできるだけ多くの空き領域が確保されます。ガベージ コレクターの機能は、到達できないオブジェクトを見つけて削除することです。
オブジェクトの割り当て
オブジェクトが割り当てられると、JRockit JVM はオブジェクトのサイズをチェックします。小さなオブジェクトと大きなオブジェクトを区別します。サイズの大小は、JVM バージョン、ヒープ サイズ、ガベージ コレクション戦略、および使用するプラットフォームによって異なります。オブジェクトのサイズは通常 2 ~ 128 KB です。
月に何週間
小さなオブジェクトは、ヒープの空きチャンクであるスレッド ローカル エリア (TLA) に保存されます。 TLA は他のスレッドと同期しません。 TLA がいっぱいになると、新しい TLA を要求します。
一方、TLA 内に収まらない大きなオブジェクトは、ヒープに直接割り当てられます。スレッドが若いスペースを使用している場合、スレッドは古いスペースに直接保存されます。大きなオブジェクトでは、スレッド間のより多くの同期が必要になります。
Java ガベージ コレクターとは何ですか?
JVM はガベージ コレクターを制御します。 JVM はガベージ コレクションをいつ実行するかを決定します。 JVM にガベージ コレクターの実行を要求することもできます。ただし、どのような条件下でも JVM が準拠するという保証はありません。 JVM は、メモリが不足していることを検知すると、ガベージ コレクタを実行します。 Java プログラムがガベージ コレクターを要求すると、JVM は通常、すぐにその要求を許可します。リクエストが受け入れられるかどうかは保証されません。
理解すべき点は、「 オブジェクトがガベージ コレクションの対象となるのはいつですか? '
すべての Java プログラムには複数のスレッドがあります。各スレッドには実行スタックがあります。 Java プログラムで実行するスレッドが main() メソッドです。これで、ライブ スレッドがアクセスできないオブジェクトはガベージ コレクションの対象となると言えます。ガベージ コレクターは、そのオブジェクトが削除の対象であるとみなします。プログラムにオブジェクトを参照する参照変数があり、その参照変数がライブ スレッドで使用できる場合、このオブジェクトは呼び出されます。 到達可能な 。
ここで次のような疑問が生じます。 Java アプリケーションがメモリ不足になることはありますか? '
答えは「はい」です。ガベージ コレクション システムは、使用されていないオブジェクトをメモリから取得しようとします。ただし、多数のライブ オブジェクトを維持している場合、ガベージ コレクションでは十分なメモリがあることが保証されません。使用可能なメモリのみが効果的に管理されます。
文字列に長い
ガベージ コレクションの種類
ガベージ コレクションには次の 5 種類があります。
マークアンドスイープアルゴリズム
JRockit JVM は、ガベージ コレクションを実行するためにマークおよびスイープ アルゴリズムを使用します。これには、マーク フェーズとスイープ フェーズの 2 つのフェーズが含まれます。
マークフェーズ: スレッド、ネイティブ ハンドル、およびその他の GC ルート ソースからアクセスできるオブジェクトは、ライブとしてマークされます。すべてのオブジェクト ツリーには複数のルート オブジェクトがあります。 GC ルートには常に到達可能です。つまり、ルートにガベージ コレクション ルートを持つすべてのオブジェクトです。使用中のすべてのオブジェクトを識別してマークし、残りはガベージと見なすことができます。
スイープフェーズ: このフェーズでは、ヒープを走査して、ライブ オブジェクト間のギャップを見つけます。これらのギャップは空きリストに記録され、新しいオブジェクトの割り当てに使用できます。
マークとスイープには 2 つの改良バージョンがあります。
Javaの比較
同時マークとスイープ
これにより、ガベージ コレクションの大部分の間、スレッドが実行を継続できるようになります。マーキングには次の種類があります。
平行マークとスイープ
可能な限り高速にガベージ コレクションを実行するために、システム内の利用可能なすべての CPU が使用されます。並列ガベージ コレクターとも呼ばれます。並列ガベージ コレクションの実行時にはスレッドは実行されません。
マークとスイープの長所
- これは繰り返し行われるプロセスです。
- 無限ループです。
- アルゴリズムの実行中に追加のオーバーヘッドは許可されません。
マークとスイープの短所
- ガベージ コレクション アルゴリズムの実行中は、通常のプログラムの実行が停止されます。
- プログラム上で複数回実行されます。