ホームページ Java &#&チュートリアル Java ガベージ コレクションの詳細な説明

Java ガベージ コレクションの詳細な説明

Jan 17, 2017 pm 03:49 PM

1. ガベージ コレクション アルゴリズムの中心的な考え方
Java 言語は、使用中のオブジェクトを追跡し、使用されなくなった (参照された) オブジェクトを検出してリサイクルするためのガベージ コレクション メカニズムを確立しました。このメカニズムにより、動的メモリ割り当てで発生する可能性のある 2 つの危険、つまり過剰なメモリ ガベージによるメモリ枯渇と、不適切なメモリ解放による不正なメモリ参照を効果的に防ぐことができます。

ガベージ コレクション アルゴリズムの中心的な考え方は、仮想マシンの利用可能なメモリ領域、つまりヒープ領域内のオブジェクトを識別することです。オブジェクトが参照されている場合、それは逆にリビング オブジェクトと呼ばれます。オブジェクトが参照されなくなった場合、それはガベージ オブジェクトであり、再割り当てのために占有しているスペースを再利用できます。ガベージ コレクション アルゴリズムの選択とガベージ コレクション システム パラメーターの適切な調整はシステムのパフォーマンスに直接影響するため、開発者はより深い理解を必要とします。

2. メイン GC (ガベージ コレクター) のトリガー条件
JVM は非常に頻繁にセカンダリ GC を実行しますが、この GC にかかる時間は非常に短いため、システムへの影響はほとんどありません。さらに注目に値するのは、メイン GC のトリガー条件です。これはシステムに重大な影響を与えるためです。一般に、メイン GC をトリガーする条件は 2 つあります:

(1) アプリケーションがアイドル状態のとき、つまりアプリケーション スレッドが実行されていないとき、GC が呼び出されます。 GC は最も優先度の低いスレッドで実行されるため、アプリケーションがビジー状態の場合、以下の条件を除いて GC スレッドは呼び出されません。

(2) Javaヒープメモリが不足した場合、GCが呼び出されます。アプリケーション スレッドが実行中で、実行プロセス中に新しいオブジェクトが作成されるとき、その時点でメモリ領域が不十分な場合、JVM は強制的に GC スレッドを呼び出して、新しい割り当てのためにメモリを再利用します。 1 回の GC 後にメモリ割り当て要件を満たすことができない場合、JVM はさらに 2 回の GC 試行を実行し、それでも要件を満たすことができない場合、JVM は「メモリ不足」エラーを報告し、Java アプリケーションは次のことを行います。停止。

メイン GC を実行するかどうかはシステム環境に基づいて JVM によって決定され、システム環境は常に変化するため、メイン GC の動作は不確実であり、いつ必ず発生するかを予測することはできませんが、アプリケーションの場合、メイン GC が繰り返し実行されるため、長期的な運用には必ず必要になります。

3. GC のオーバーヘッドを軽減するための対策
上記の GC メカニズムによれば、プログラムの動作はシステム環境の変化に直接影響を及ぼし、それによって GC のトリガーに影響を与えます。 GC の特性に応じた設計とコーディングを行わないと、メモリの保持などの悪影響が次々と発生します。これらの影響を回避するには、ガベージを減らし、GC プロセスのオーバーヘッドを可能な限り減らすことが基本原則です。具体的な対策としては、以下のような点が挙げられます。

(1) System.gc() を明示的に呼び出さない
この関数は、JVM がメイン GC を実行することを推奨していますが、これは単なる提案であり、保証するものではありません。メイン GC の頻度、つまり断続的な一時停止の回数が増加します。ここで特別な説明が必要なのは、コードに示されている System.gc() の呼び出しが必ずしも GC を実行できるわけではないということです。これは、finalize() メソッド、つまり System.gc() を積極的に呼び出すことで確認できます。毎回、finalize() メソッドが呼び出されるわけではありません。 Finalize() メソッドの特徴は、オブジェクトがリサイクルされる前に最初に Finalize() メソッドが呼び出されることです。

(2) 一時オブジェクトの使用を最小限に抑える
一時変数の使用量を減らすことは、一時オブジェクトの生成を減らすことと同じであり、その結果、上記の 2 番目のトリガー条件が発生するまでの時間が長くなります。 、メインGCの可能性を減らします。

(3) 使用されていないオブジェクトは明示的に Null に設定するのが最善です
一般的に、Null オブジェクトはガベージとして扱われるため、未使用のオブジェクトを明示的に Null に設定すると、GC コレクターがガベージを判断しやすくなります。 GCの効率。

(4) 文字列を蓄積するために String の代わりに StringBuffer を使用してみてください (JAVA の String と StringBuffer については、このブログの別の記事を参照してください)
String は固定長の文字列オブジェクトであるため、String オブジェクトを蓄積するとき、それらはString オブジェクトですが、Str5=Str1+Str2+Str3+Str4 などの新しい String オブジェクトを再作成します。各「+」演算を新しい String オブジェクトで作成する必要があるため、このステートメントの実行中に複数のガベージ オブジェクトが生成されます。 , しかし、これらの遷移オブジェクトはシステムにとって実質的な意味はなく、ゴミが増えるだけです。この状況を回避するには、代わりに StringBuffer を使用して文字列を蓄積します。StringBuffer は可変長であるため、元のベースに基づいて拡張され、中間オブジェクトは生成されません。

(5) Int や Long などの基本型を使用できる場合は、Integer オブジェクトや Long オブジェクトは必要ありません。
基本型変数は、対応するオブジェクトよりも占有するメモリ リソースがはるかに少ないため、必要がない場合は使用するのが最善です。基本的な変数を使用します。整数を使用する必要があるのはどのような場合ですか?

(6) 静的オブジェクト変数はできるだけ使用しないでください
静的変数はグローバル変数であり、GC によってリサイクルされません。常にメモリを占有します。

(7) オブジェクトの作成または削除の時間を分散する
短期間に大量の新しいオブジェクト、特に大きなオブジェクトを集中して作成すると、大量のメモリが必要になる場合があります。この状況では、JVM はメイン GC を実行してメモリを再利用するか、メモリ フラグメントを統合してメイン GC の頻度を高めることしかできません。同じ原則がオブジェクトの集中削除にも当てはまります。これにより、大量のガベージ オブジェクトが突然出現し、空き領域が必然的に減少するため、次回新しいオブジェクトが作成されるときにメイン GC が強制される可能性が大幅に高まります。

4. ガベージ コレクション アルゴリズム
(1) 参照カウント コレクター
参照カウントはガベージ コレクションの初期の戦略です。このアプローチでは、ヒープ内のすべてのオブジェクトに参照カウントがあります。オブジェクトが作成され、そのオブジェクトへの参照が変数に割り当てられると、オブジェクトの参照カウントは 1 に設定されます。たとえば、新しいオブジェクト A a=new A(); を作成すると、a が別の変数 b に割り当てられます (つまり、b=a)。オブジェクト a の参照カウントは +1 になります。他の変数にこのオブジェクトへの参照が割り当てられると、カウントは 1 つ増加します。オブジェクトへの参照が有効期間を超えるか、新しい値に設定されると、オブジェクトの参照カウントは 1 つ減ります。たとえば、b=c の場合、a の参照カウントは -1 になります。参照カウントが 0 のオブジェクトはすべてガベージ コレクションの対象になります。オブジェクトがガベージ コレクションされると、そのオブジェクトが参照するオブジェクトの数は 1 つ減ります。このアプローチでは、1 つのオブジェクトのガベージ コレクションが、その後の他のオブジェクトのガベージ コレクション アクションにつながる可能性があります。たとえば、A a=new A();b=a; b がガベージ コレクションされると、a の参照カウントが 0 になり、a もガベージ コレクションされます。

この方法の利点: 参照カウント コレクターは迅速に実行でき、プログラムの実行と連動します。このリマインダーは、プログラムを長時間中断できないリアルタイム環境で役立ちます。

メソッドの欠点: 参照カウントではサイクル (つまり、2 つ以上のオブジェクトが相互参照) を検出できません。ループの例としては、親オブジェクトが子オブジェクトへの参照を持ち、さらに子オブジェクトが親オブジェクトを参照する場合があります。このように、実行中のプログラムのルート オブジェクトからオブジェクト ユーザーに到達できなくなったとしても、オブジェクト ユーザーのカウントが 0 になることはあり得ません。もう 1 つの欠点は、参照カウントが増加または減少するたびに追加のオーバーヘッドが発生することです。

(2) Trace Collector
ガベージ検出は通常、ルート オブジェクトのコレクションを構築し、これらのルート オブジェクトから開始して到達可能性をチェックすることによって実装されます。実行中のプログラムがアクセスできるルート オブジェクトとオブジェクトとの間に参照パスが存在する場合、オブジェクトは到達可能です。ルート オブジェクトはプログラムから常にアクセス可能です。これらのルート オブジェクトから始まり、タッチできるオブジェクトはすべて「アクティブ」オブジェクトとみなされます。触れることができないオブジェクトは、今後のプログラムの実行に影響を与えないため、ガベージとみなされます。

トレース コレクターは、ルート ノードから開始してオブジェクト参照グラフを追跡します。追跡中に遭遇したオブジェクトには、特定の方法でマークが付けられます。一般に、オブジェクト自体にマーカーを設定するか、別のビットマップを使用してマーカーを設定します。追跡が終了すると、マークされていないオブジェクトは到達できなくなり、収集できるようになります。

基本的な追跡アルゴリズムは「マークアンドクリア」と呼ばれます。この名前は、ジャンク電話の 2 つの段階を示しています。マーキング フェーズでは、ガベージ コレクターは参照ツリーを走査し、検出された各オブジェクトをマークします。クリーンアップ フェーズでは、マークされていないオブジェクトが解放され、オブジェクトの解放後に取得されたメモリが実行プログラムに返されます。 Java 仮想マシンでは、クリーンアップ ステップにオブジェクトのファイナライズを含める必要があります。

Java ガベージ コレクションと関連記事のさらに詳細な説明については、PHP 中国語 Web サイトに注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか? Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか? Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか? カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか? Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

Javaで機能的なプログラミング技術を実装するにはどうすればよいですか? Javaで機能的なプログラミング技術を実装するにはどうすればよいですか? Mar 11, 2025 pm 05:51 PM

この記事では、Lambda式、Streams API、メソッド参照、およびオプションを使用して、機能プログラミングをJavaに統合することを調べます。 それは、簡潔さと不変性を通じてコードの読みやすさと保守性の改善などの利点を強調しています

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか? キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか? Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか? 高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか? Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか? 非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか? Mar 11, 2025 pm 05:51 PM

この記事では、単一のスレッドで複数の接続を効率的に処理するためにセレクターとチャネルを使用して、非ブロッキングI/O用のJavaのNIO APIについて説明します。 プロセス、利点(スケーラビリティ、パフォーマンス)、および潜在的な落とし穴(複雑さ、

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか? 適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか? Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか? ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか? Mar 11, 2025 pm 05:53 PM

この記事では、ネットワーク通信のためのJavaのソケットAPI、クライアントサーバーのセットアップ、データ処理、リソース管理、エラー処理、セキュリティなどの重要な考慮事項をカバーしています。 また、パフォーマンスの最適化手法も調査します

See all articles