JAVA GC原理の詳細

5028 ワード

ほとんどの場合、GCについての理解は浅い意味にすぎませんが、内部の実装原理を詳しく説明します.GCを説明する前に、JVMのメモリ構造を理解してから、GCが何をしているのかを理解する必要があります.
一.JVMメモリ構造
JVMメモリ構造は、以下の5つの部分から構成されています.
1.プログラムカウンタ(Program Conuter Register)
現在のスレッドがバイトコードを実行する行番号インジケータである小さなメモリ領域です.バイトコード解釈ワークベンチは、このカウンタの値を変更することによって、次の実行する必要がある命令を選択します.スレッドのプライベートメモリであり、OOM異常のない唯一の領域でもあります.
2.Java仮想マシンスタックエリア(Java Virtual Machine Stacks)
すなわち、通常、Javaメソッドが実行するメモリモデルを記述するスタック領域であり、各メソッドが実行されると、ローカル変数テーブル、オペランドスタック、ダイナミックリンク、メソッド出口などを格納するスタックフレーム(Stack Frame)が作成される.各メソッドは、1つのスタックフレームが仮想マシンスタック内でスタックからスタックを出るプロセスに相当する完了まで呼び出される.この領域はスレッドプライベートメモリでもあり、スレッドが要求するスタックの深さが仮想マシンが許容する深さより大きい場合、StackOverflowErrorが放出される可能性があります.仮想マシンスタックが動的に拡張できる場合、十分なメモリに動的に申請できないまで拡張すると、OOM例外が放出されます.
3.ローカルメソッドスタック(Native Method Stacks)
ローカルメソッドスタックは、仮想マシンがJavaメソッドを実行する仮想マシンスタックと、ローカルメソッドスタックが仮想マシンに使用されるNativeメソッドサービスである点で、仮想マシンスタックと非常に似ています.
4.ヒープゾーン(Heap)
すべてのオブジェクトインスタンスと配列はスタック領域に割り当てられ、スタック領域はGCが主に管理する領域である.堆積区は新生代、旧年代に細分化され、新生代は1つのEden区と2つのSurvivor区に分けられる.このブロックメモリはすべてのスレッド共有領域であり、スタックにインスタンス割り当てが完了するのに十分なメモリがない場合、OOM例外が放出されます.
5.メソッド領域(Method Area)
メソッド領域もすべてのスレッド共有領域であり、仮想マシンにロードされたクラス情報、定数、静的変数、インスタントコンパイルされたコードなどのデータを格納するために使用されます.GCはこの領域ではあまり出現しないが,この領域のメモリ回収の目標は主に定数プールの回収とタイプのアンロードであり,回収メモリは比較的少ないため,この領域を永続世代(Permanent Generation)と呼ぶこともある.メソッド領域がメモリ割り当てを満たすことができない場合、OOM例外が放出されます.
二.GC原理
GCの原理メカニズムについて、主に次の3つの問題を明らかにします.
  • はいつ回収しますか?
  • 回収する必要があるものは何ですか?
  • はどうやって回収しますか?

  • 1.いつ回収しますか.
    1.オブジェクトは新生代のEden領域に優先的に割り当てられ、スペースが足りない場合はMinor GCを1回行い、クリーンアップ頻度が高い.2.Full GCは古い時代に発生し、スペースが足りないときにFull GCを1回行い、それに伴ってMinor GCも1回行われた.3.Minor GCを行うと、その都度古い年代に昇格する対象の平均値が古い年代の余剰スペースより大きいかどうかを判断し、大きい場合はフルGCを1回行い、小さい場合はHandlePromotionFailure設定が保証失敗を許可しているかどうかを判断し、許可されている場合はMinor GCを行い、許可されていない場合はフルGCに変更する.
        GC        ,      `   ` `   `
    * 【   】    Eden   Survivor 。 new        ,    。
    * 【   】 new          (     Eden    Survivor          ),                           。

    2.回収する必要があるものは何ですか.
    finalize()メソッドが呼び出されると、上記のようにシーンをクリーンアップする必要があります.
    *    finalize()  ?
    
        GC          finalize()  ,              。
    
    *       finalize()  ?
    
    1.GC    ,    System.gc();(  System.gc()    JVM   ,      JVM   )
    2.     ,        finalzie
    3.    finalize
    

    3.回収方法
    JVMは異なるコレクタによって異なるアルゴリズムの組み合わせを使用して回収の効果を達成する
    ###       
    
    * mark-sweep(  -  )-            ,              。
    
      :1.               。2.                 。
    
    * copying(  )-          
    
           Eden 、  Survivor (Survivor0、Survivor1),Eden Survivor  8:1。     Eden       Survivor0 ,  Eden , Survivor0     , Eden Survivor0         Survivor1 ,  Eden  Survivor0 ,    Survivor0 Survivor1 ,  Survivor1    ,    
    
    * mark-compact(  -  )
    
             。         ,              ,               。
    
    * generational collection(  )
    
             ,                 。     ,      ,      。     ,    ,               ,     “  -  ”  “  -  ”       。
    
    --------
    
    ###      
    
    * Serial 、Serial Old     [-XX:+UseSerialGC,   Serial + Serial Old     ]
    
            ,                        (stop the world),              
    
    * ParNew     [-XX:UseParallelGC,   Parallel Scavenge + Serial Old     ]
    
    serial          。ParNew      Server                 ,  Serial    ,     CMS       
    
    * Parallel Scavenge 、Parallel Old     [-XX:GCTimeRatio,-XX:MaxGCPauseMillis]
    
          GCTimeRatio MaxGCPauseMillis,                   ,             。
    
    * CMS (Concurrent Mark Sweep)    [-XX:UseConcMarkSweepGC,   ParNew + CMS + Serial Old     ]
    
                      。
    
      
    
    1.    (CMS initial mark),  GC Roots         ,    
    2.    (CMS concurrent mark),  GC Roots Tracing
    3.    (CMS remark),                                    ,        
    4.    (CMS concurrent sweep)    
    
      
    1.     CPU  ,          (CPU  +3)/4。
    2. CMS           (CMS            ,             GC    ),    “Concurrent Mode Failure”      Full GC   。    -XX:CMSInitiatingOccupancyFraction   。
    3.   -              Full GC(   Serial Old        )。    -XX:UseCMSCompactAtFullCollection、-XX:CMSFullGCsBeforeCompaction   。
    
    * G1(Garbage-First)     [-XX:+UseG1GC]
    
    Java                 ,    Java               `Region`,             ,     `Region`   。G1           (>4GB)      。      Region         ,          ,           ,         `Region`。
    
      
    1.     
    2.    
    3.    
    4.      
    
      
    1.    (Initial Marking)
    2.    (Concurrent Marking)
    3.    (Final Marking)
    4.    (Live Data Counting and Evacuation)

    補足:
    1、パラレルParallel -XX:+UseParalleGC, 複数のゴミ収集スレッドが並行して動作するが、この時点でユーザースレッドは依然として待機状態にある2、同時Concurrent UseConcMarkSweepGC, はユーザースレッドがゴミ収集スレッドと同時に実行することを指す(ただし必ずしも並列ではなく、交互に実行する可能性がある)、ユーザープログラムは引き続き実行し、ゴミ収集プログラムは別のCPUで実行する
    シリアルプロセッサ:Serial --適用状況:データ量が比較的小さい(100 M程度);シングルプロセッサで応答時間が要求されないアプリケーション.--欠点:スモールアプリケーションパラレルプロセッサ:UseParalleGC--適用状況:「スループットに高い要求がある」,マルチCPU,アプリケーション応答時間に要求のない中・大規模アプリケーション.例:バックグラウンド処理、科学計算.--欠点:応用応答時間が比較的長い同時プロセッサ:UseConcMarkSweepGC--適用状況:「応答時間に高い要求がある」、マルチCPU、応用応答時間に高い要求がある中、大型応用.例:Webサーバ/アプリケーションサーバ、電気通信交換、統合開発環境.