Garbage Collection(GC)に関しては、多くの人が自然にJavaと関連付けます。 Javaでは、プログラマーは動的なメモリの割り当てとガベージコレクションを気にする必要はありません。これはすべて、処理するためにJVMに任されています。
名前が示すように、ゴミコレクションは、ゴミで占有されているスペースを解放することです。 Javaでは、どのようなオブジェクトが「ごみ」と見なされますか?したがって、いくつかのオブジェクトがゴミであると判断された場合、リサイクルに使用するためにどの戦略を使用する必要がありますか?現在の商用仮想マシンの典型的なゴミコレクターは何ですか?これらの問題を1つずつ議論しましょう。この記事のディレクトリの概要は次のとおりです。
オブジェクトが「ごみ」であるかどうかを判断する方法は?
典型的なガベージコレクションアルゴリズム典型的なゴミコレクター
1.オブジェクトが「ごみ」であるかどうかを判断する方法は?
このセクションでは、最初に最も基本的な質問を理解しています。オブジェクトが「ごみ」であると判断した場合は?ガベージコレクターのタスクは、新しいオブジェクトが使用するためにゴミオブジェクトが占めるスペースをリサイクルすることであるため、ゴミコレクターはオブジェクトが「ゴミ」であるとどのように判断しますか?つまり、オブジェクトをリサイクルできると判断する方法。
Javaでは、参照を介してオブジェクトに関連付けられています。つまり、オブジェクトを操作する場合は、参照を使用して行う必要があります。その後、簡単な方法は、参照カウントによってオブジェクトをリサイクルできるかどうかを判断することであることは明らかです。一般性を失うことなく、オブジェクトに関連する参照がない場合、オブジェクトが基本的に他の場所で使用される可能性が低く、オブジェクトがリサイクル可能なオブジェクトになることを意味します。この方法は、参照カウント方法になります。
この方法は、その単純な実装と高効率によって特徴付けられますが、循環参照の問題を解決することはできないため、この方法はJavaで採用されていません(Pythonは参照カウント方法を使用します)。次のコードを見てください。
public class main {public static void main(string [] args){myobject object1 = new Myobject(); myobject object2 = new Myobject(); object1.object = object2; object2.object = object1; object1 = null; object2 = null; }} class myobject {public object object = null;}最後の2つの文はobject1とobject2をnullに割り当てます。つまり、object1とobject2によって指されたオブジェクトはもはやアクセスできなくなりますが、互いに参照するため、参照カウントは0ではありません。
この問題を解決するために、Javaでアクセシビリティ分析方法が採用されています。この方法の基本的なアイデアは、一連の「GCルーツ」オブジェクトを出発点として検索することです。 「GC Roots」とオブジェクトの間にアクセス可能なパスがない場合、オブジェクトは到達不能と言われます。ただし、到達不能であると判断されたオブジェクトは、必ずしもリサイクル可能なオブジェクトになるとは限らないことに注意する必要があります。到達不能と判断されるオブジェクトは、リサイクル可能なオブジェクトになるために、少なくとも2つのマーキングプロセスを通過する必要があります。これら2つのマーキングプロセス中にリサイクル可能なオブジェクトになる可能性がまだない場合、それは基本的にリサイクル可能なオブジェクトになります。
アクセシビリティ分析方法がどのように操作されているかについては、まだはっきりと理解していません。友達がもっと明確であれば、アドバイスをください。
以下の例を見てみましょう。
object aobj = new object(); object bobj = new object(); object cobj = new object(); aobj = bobj; aobj = cobj; cobj = null; aobj = null;
どのラインがオブジェクトをリサイクル可能にする可能性がありますか? 7行目のコードにより、オブジェクトがリサイクル可能なオブジェクトになります。自分で考えることが読者に任される理由について。
別の例を見てみましょう。
string str = new String( "hello"); softreference <string> sr = new softreference <string>(new String( "Java")); weakReference <string> wr = new weakReference <string>(new String( "world"));
これらの3つの文のうち、文字列オブジェクトをリサイクル可能にするものはどれですか?文2および3、および文2は、メモリが不十分な場合にリサイクル可能なオブジェクトとして文字列オブジェクトを決定し、3番目の文では、いずれにせよ、リサイクル可能なオブジェクトとして文字列オブジェクトが決定されます。
最後に、オブジェクトが通常遭遇するリサイクル可能なオブジェクトとして判断される一般的な状況を要約しましょう。
1)NULLへの参照の値を表示するか、次のコードなどの新しいオブジェクトをオブジェクトに既に指している参照を指します。
オブジェクトobj = new object(); obj = null; object obj1 = new object(); object obj2 = new object(); obj1 = obj2;
2)次のコードなど、指摘されたオブジェクトへのローカル参照:
void fun(){...... for(int i = 0; i <10; i ++){object obj = new object(); System.out.println(obj.getClass()); }}ループが実行されるたびに、生成されたオブジェクトオブジェクトはリサイクル可能なオブジェクトになります。
3)弱い参照のみが、次のようなオブジェクトに関連付けられています。
weakreference <string> wr = new weakreference <string>(new String( "world"));
2。典型的なガベージコレクションアルゴリズム
どのガベージをリサイクルできるかを判断した後、ゴミコレクターが行う必要があるのはゴミ収集を開始することですが、1つの問題は、ゴミを効率的に収集する方法です。 Java Virtual Machine Specificationは、ごみ収集器の実装方法に関する明確な規制を行っていないため、各メーカーの仮想マシンはさまざまな方法でガベージコレクターを実装できます。そのため、いくつかの一般的なガベージコレクションアルゴリズムの中核的なアイデアのみについて説明します。
1.マークスイープ(マーククリア)アルゴリズム
これは、最も基本的なごみ収集アルゴリズムです。それが最も基本的であると言われている理由は、実装するのが最も簡単で最も単純なアイデアであるためです。マーククリアリングアルゴリズムは、マーキングステージとクリアリング段階の2つの段階に分かれています。マーキング段階のタスクは、リサイクルする必要があるすべてのオブジェクトをマークすることであり、クリアリングステージは、マークされたオブジェクトが占めるスペースをリサイクルすることです。特定のプロセスを以下の図に示します。
図から、マーククリアリングアルゴリズムの実装が簡単であることが簡単にわかりますが、メモリフラグメントを簡単に生成するのは深刻な問題があります。断片が多すぎると、後続のプロセスで大きなオブジェクトにスペースを割り当て、新しいガベージコレクションアクションを事前にトリガーするときに、十分なスペースを見つけることができなくなる可能性があります。
2。コピー(コピー)アルゴリズム
Mark-Sweepアルゴリズムの欠点を解決するために、コピーアルゴリズムが提案されました。利用可能なメモリを容量ごとに2つの等しいサイズに分割し、一度に1つのピースのみを使用します。このメモリの一部を使用したら、まだ生きているオブジェクトを別のピースにコピーしてから、使用済みのメモリスペースを一度にクリーンアップして、メモリの断片化の問題が発生しないようにします。特定のプロセスを以下の図に示します。
このアルゴリズムは実装が簡単で、実行が効率的であり、メモリの断片化を簡単に生成するのは簡単ではありませんが、使用できるメモリが元のメモリの半分に縮小されるため、メモリスペースを使用するのは費用がかかります。
明らかに、コピーアルゴリズムの効率は、生き残ったオブジェクトの数と多くの関係があります。多くの生き残ったオブジェクトがある場合、コピーアルゴリズムの効率が大幅に削減されます。
3.mark-compact(Mark-Collation)アルゴリズム
コピーアルゴリズムの欠点を解決し、メモリスペースを最大限に活用するために、Mark-Compactアルゴリズムが提案されています。アルゴリズムはMark-Sweepと同じですが、マークを完成させた後、リサイクル可能なオブジェクトを直接クリーンアップするのではなく、すべての生きたオブジェクトを一端に移動し、エンド境界の外側のメモリをクリーンアップします。特定のプロセスを以下の図に示します。
4。世代コレクションアルゴリズム
現在、ジェネレーションコレクションアルゴリズムは、ほとんどのJVMガベージコレクターで使用されています。その核となるアイデアは、オブジェクトの生存のライフサイクルに応じて、記憶をいくつかの異なる領域に分割することです。一般的に言えば、ヒープ領域は古い世代と若い世代に分かれています。古い世代の特徴は、ごみが収集されるたびにリサイクルする必要があるのは少数のオブジェクトのみが、新世代の特徴は、ガベージを収集するたびに多数のオブジェクトをリサイクルする必要があることです。次に、さまざまな世代の特性に従って、最も適切なコレクションアルゴリズムを採用できます。
現在、ほとんどのゴミコレクターは新世代のコピーアルゴリズムを採用しています。なぜなら、ほとんどのオブジェクトは、ゴミコレクションが収集されるたびにリサイクルする必要があるため、コピーする必要がある操作の数は比較的小さいため、実際には、新世代のスペースは1:1の比率に応じて分割されていません。一般的に言えば、新世代はより大きなエデン空間と2つの小さな生存空間に分かれています。エデンスペースとサバイバースペースの1つが使用されるたびに、リサイクルすると、エデンとサバイバーのまだ生存するオブジェクトが別の生存者スペースにコピーされ、次に使用されたばかりのエデンとサバイバースペースが掃除されます。
老年は毎回少数のオブジェクトのみがリサイクルされることであるため、マークコンパクトアルゴリズムが一般的に使用されます。
ヒープ領域の外側には、クラスクラス、定数、メソッドの説明などを保存するために使用される永続的な生成である別の世代があることに注意してください。永続的な生成のリサイクルは、主に廃棄された定数と役に立たないクラスの2つの部分をリサイクルします。
3.典型的なゴミコレクター
ガベージコレクションアルゴリズムは、メモリリサイクルの理論的基礎であり、ガベージコレクターはメモリリサイクルの特定の実装です。以下は、ホットスポット(JDK 7)仮想マシンによって提供されるいくつかのゴミコレクターの説明です。ユーザーは、自分のニーズに応じて各時代に使用されるコレクターを組み合わせることができます。
1.上/シリアルの古い
シリアル/シリアルの古いコレクターは、最も基本的で最古のコレクターです。これは単一のスレッドコレクターであり、ガベージコレクションを実行するときにすべてのユーザースレッドを一時停止する必要があります。シリアルコレクターは、コピーアルゴリズムを使用した新世代のコレクターであり、シリアル古いコレクターは、Mark-Compactアルゴリズムを使用して、古い世代のコレクターです。その利点は、それがシンプルで効率的であることですが、その欠点は、ユーザーに一時停止を引き起こすことです。
2.Parnew
Parnew Collectorは、ガベージコレクションに複数のスレッドを使用するシリアルコレクターのマルチスレッドバージョンです。
3.並列スカベンジ
Parallel Scavenge Collectorは、新世代のマルチスレッドコレクター(並列コレクター)です。リサイクル中に他のユーザースレッドを一時停止する必要はありません。コピーアルゴリズムを使用します。このコレクターは、最初の2人のコレクターとは異なります。主に制御されたスループットを達成することです。
4.平行古い
Parallel Oldは、マルチスレッドおよびマークコンパクトアルゴリズムを使用した、Parallel Scavenge Collector(Parallel Collector)の古いバージョンです。
5.cms
CMS(現在のマークスイープ)コレクターは、最短の回復の一時停止時間を取得することを目的としたコレクターです。これは、Mark-Sweepアルゴリズムを使用する同時コレクターです。
6.G1
G1コレクターは、今日のコレクターテクノロジー開発において最も最先端の成果です。これは、マルチCPUおよびマルチコア環境を最大限に活用できるサーバー側アプリケーションのコレクターです。したがって、これは並行した並行性コレクターであり、予測可能な一時停止時間モデルを構築できます。
メモリの割り当てについてのいくつかのことは次のとおりです。
一般的な方向では、オブジェクトのメモリ割り当てがヒープに割り当てられます。オブジェクトは主に新世代のエデン空間と宇宙から割り当てられ、まれに老年期に直接割り当てられます。新世代のエデンスペースと空間からのスペースが不十分な場合、GCが開始されます。 GCが実行されると、エデンスペースと空間からオブジェクトに対応し、エデンスペースと空間から配置できます。
GCプロセス中に、エデンスペースと宇宙からの生き残ったオブジェクトが宇宙に移動され、エデンスペースとスペースが掃除されます。掃除中にオブジェクトを保存するのに十分なスペースで十分にできない場合、オブジェクトは老年に移動します。 GCの後、エデンスペースとスペースが使用されます。次にGCをGCにすると、存続するオブジェクトがスペースからコピーされ、ループが繰り返されます。オブジェクトがサバイバーエリアでGCを1回逃げると、オブジェクトの年齢が1増加します。デフォルトでは、オブジェクトが15歳に達すると、老年期の中年に移動します。
一般的に言えば、大きなオブジェクトは老年に直接割り当てられます。いわゆる大きなオブジェクトは、大量の連続ストレージスペースを必要とするオブジェクトを指します。最も一般的なタイプの大きなオブジェクトは、次のような大きな配列です。
byte [] data = new byte [4*1024*1024]
このタイプの保管スペースは、通常、高齢者に直接割り当てられます。
もちろん、割り当てルールは100%固定されていません。これは、どのような種類のガベージコレクターの組み合わせとJVMの関連パラメーターが現在使用されているかに依存します。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。