JVMゴミ回収アルゴリズム


ごみ回収とは
プログラムの実行には必ずメモリリソースを申請する必要があります.無効なオブジェクトリソースはタイムリーに処理しないとメモリリソースを占有し続け、最終的にメモリオーバーフローを引き起こすため、メモリリソースの管理は非常に重要です.プログラマーがメモリの解放の問題をあまり考えずにコードの実現に集中できるようにするために、Java言語では、自動的なゴミ回収メカニズム、つまり私たちがよく知っているGCがあります.
ごみ回収メカニズムがあれば、プログラマーはメモリの申請に関心を持つだけで、メモリの解放はシステムによって自動的に識別されます.すなわち,自動ごみ回収のアルゴリズムが重要になり,アルゴリズムの不合理さによりメモリリソースが解放されない場合,同様にメモリオーバーフローを招く可能性がある.
ごみ回収の一般的なアルゴリズム
自動化された管理メモリリソースは、ゴミ回収メカニズムによって計算され、有効なオブジェクトと無効なオブジェクト、無効なオブジェクトについて回収処理されるアルゴリズムが必要です.よく見られるごみ回収アルゴリズムには,参照カウント法,タグクリア法,タグ圧縮法,複製アルゴリズム,世代分けアルゴリズムなどがある.
リファレンスカウントほう
引用カウントは歴史が最も古いアルゴリズムで、最も早いGeorge E.Collinsは1960年に初めて提案され、50年後の今日、このアルゴリズムは依然として多くのプログラミング言語で使用されている.
1.原理は1つのオブジェクトAがあると仮定し、いずれかのオブジェクトAに対する参照は、オブジェクトAの参照カウンタ+1であり、参照に失敗した場合、オブジェクトAの参照カウンタは-1であり、オブジェクトAのカウンタの値が0であれば、オブジェクトAが参照されていないことを示し、回収することができる.
2.メリットとデメリット
メリット:
  • はリアルタイム性が高く、メモリが足りないまで待つことなく回収を開始し、実行時に対象のカウンタが0であるかどうかによって
  • を直接回収することができる.
  • ゴミ回収中、アプリケーションは停止する必要はありません.メモリを申請するときにメモリが不足している場合は、outofmemberエラー
  • をすぐに報告します.
  • 領域性で、オブジェクトのカウンタを更新すると、そのオブジェクトに影響するだけで、全オブジェクト
  • はスキャンされない.
    欠点:
  • オブジェクトが参照されるたびにカウンタを更新する必要があり、時間オーバーヘッド
  • がある.
  • CPUリソースを浪費し、メモリが十分であっても実行時にカウンタの統計
  • を行う.
  • 循環引用問題(最大の欠点)
  • を解決できない
    ループリファレンスとは?
    class TestA{
        public TestB b;
    }
    class TestB{ 
        public TestA a;
    }
    public class Test {
        public static void main(String[] args) {
            TestA a=new TestA();
            TestB b=new TestB();
            a.b=b;
            b.a=a;
            a=null;
            b=null;
        }
    }
    

    aとbはnullであるが、aとbには循環参照があるため、aとbは永遠に回収されない.
    タグクリア
    タグクリアアルゴリズムは,ごみ回収をタグとクリアの2段階に分ける.
  • タグ:ルートノードからタグ参照を開始するオブジェクト
  • クリア:マークされていない参照オブジェクトはゴミオブジェクトであり、
  • クリアできる.
    1.原理この図はプログラム実行中のすべてのオブジェクトの状態を表し、それらのフラグビットはすべて0(つまりマークされていない、以下のデフォルト0はマークされていない、1はマークされている)であり、仮に今有効なメモリ空間が消耗したと仮定すると、JVMはアプリケーションの実行を停止しGCスレッドを開き、それからマーク作業を開始し、ルート検索アルゴリズムに従って、マークが終わった後、オブジェクトの状態を下図に示します.
    ルート検索アルゴリズムによれば、rootオブジェクトから到達可能なすべてのオブジェクトが生存するオブジェクトとしてマークされ、この時点で第1段階のマークが完了していることがわかる.次に、第2段階クリアを実行します.クリアが完了すると、残りのオブジェクトおよびオブジェクトの状態が下図のようになります.
    マークされていないオブジェクトは回収されて消去され、マークされたオブジェクトは残り、マークビットは0に戻ります.次は言うまでもなく、停止したプログラムスレッドを呼び出し、プログラムを実行させておけばいい.
    2.タグクリアアルゴリズムは、rootノードから参照されていないオブジェクトが回収される参照カウントアルゴリズムにおけるループ参照の問題を解決することができる.同様に、タグクリアアルゴリズムにも欠点があります.
  • は効率が低く、マークアップとクリアの2つの動作はすべてのオブジェクトを巡回する必要があり、GCではアプリケーションを停止する必要があり、インタラクティブな要求が高いアプリケーションではこの体験は非常に悪い.
  • タグクリアアルゴリズムによりクリーンアップされたメモリは、回収されたオブジェクトがメモリの隅々に存在する可能性があるため、クリーンアップされたメモリは一貫していない.

  • タグ圧縮アルゴリズム
    タグ圧縮アルゴリズムはタグクリアアルゴリズムに基づいて最適化改良されたアルゴリズムである.タグクリアアルゴリズムと同様に、ルートノードからオブジェクトの参照をタグ付けし、クリーンアップフェーズでは、タグ付けされていないオブジェクトを単純にクリーンアップするのではなく、生存しているオブジェクトをメモリの一端に圧縮し、境界以外のゴミをクリーンアップすることで、フラグメント化の問題を解決します.
    1.原理
    2.長所と短所長所と短所はマークアップアルゴリズムと同じで、マークアップアルゴリズムの断片化の問題を解決した.同時に、マーク圧縮アルゴリズムは一歩多くなり、オブジェクトがメモリ位置を移動するステップは、その効率にも一定の影響がある.
    アルゴリズムのコピー
    レプリケーションアルゴリズムの核心は、既存のメモリ空間を2つに分け、その中の1つだけを使用し、ゴミ回収時に使用しているオブジェクトを別のメモリ空間にコピーし、そのメモリ空間を空にし、2つのメモリの役割を交換し、ゴミの回収を完了することです.
    メモリ内のゴミオブジェクトが多い場合、コピーするオブジェクトが少ない場合は、この方法が適しており、効率が高く、逆に適していません.
    1.JVMの若い世代のメモリ容量
  • GCが始まると、オブジェクトはEdenエリアとFromというSurvivorエリアにしか存在しません.Survivorエリア「To」は空です.
  • はGCに続いて行われ、Eden区では生存しているすべてのオブジェクトが「To」にコピーされ、「From」区では生存しているオブジェクトは彼らの年齢値によって行方が決まる.年齢が一定値(年齢閾値、-XX:MaxTenuringThresholdで設定可能)に達したオブジェクトは、年老いた世代に移動され、閾値に達していないオブジェクトは「To」領域にコピーされます.
  • が今回のGCを通過した後、Eden区とFrom区はすでに空になった.このとき、「From」と「To」は彼らのキャラクターを交換します.つまり、新しい「To」は前回GC前の「From」、新しい「From」は前回GC前の「To」です.いずれにしても、ToというSurvivorエリアが空であることが保証されます.
  • GCでは、「To」領域が満たされ、「To」領域が満たされた後、すべてのオブジェクトが高齢者に移動するまで、このようなプロセスが繰り返されます.

  • 2.メリットとデメリット:
  • ゴミの対象が多い場合、効率が高い
  • クリーンアップ後、メモリに断片化がない
  • 欠点:
  • ゴミの対象が少ない場合、適用されません.例えば、古い年代のメモリ
  • に割り当てられた2つのメモリ領域は、同じ時刻に半分しか使用できず、メモリ使用率が低い
  • である.
    ぶんかつアルゴリズム
    前述したように,複数の回収アルゴリズムを紹介したが,いずれのアルゴリズムにも独自の利点と欠点があり,誰もが誰に代わることができないため,ごみ回収対象の特徴に基づいて選択することが賢明である.
    世代分けアルゴリズムは実はこのようにして、回収対象の特徴によって選択して、jvmの中で、若い世代は複製アルゴリズムを使うのに適して、古い年代はマーククリアあるいはマーク圧縮アルゴリズムを使うのに適しています.