1. 程式人生 > >深入JVM 原理(四)JVM垃圾回收流程

深入JVM 原理(四)JVM垃圾回收流程

目錄

我們所有的資料都會儲存在JVM的堆記憶體之中,但是實際的開發中會經常建立很多臨時物件和常駐物件。所以,為了保證GC的效能問題,對於GC的處理流程如下圖所示:

這裡寫圖片描述

對於整個GC流程裡,最需要處理的就是年輕代和老年代的記憶體清理操作,而元空間(永久代)都不在GC範圍內;

  1. 當現在有一個新的物件產生,那麼物件一定需要記憶體空間,於是現在就需要為該物件進行記憶體空間的申請。
  2. 首先會判斷伊甸園區是否有記憶體空間,如果此時有記憶體空間,則將新物件儲存在伊甸園區;
  3. 但如果伊甸園區的記憶體空間不足,那麼會自動執行一個 Minor GC 操作,將伊甸園區無用的記憶體空間進行清理,當清理之後會繼續判斷伊甸園區的記憶體空間是否充足?充足則將新的物件進行空間分配;
  4. 如果執行了 Minor GC 之後發現伊甸園區的記憶體依然不足,那麼這個時候會進行存貨區判斷,如果存活區有剩餘空間,則將伊甸園區的部分物件儲存在存活區,那麼隨後繼續判斷伊甸園區的記憶體空間是否充足,如何記憶體充足,則在伊甸園區進行空間分配;
  5. 如果此時存活區也已經沒有記憶體空間了,則開始判斷老年區,如果此時老年區的空間充足,則將存活區中的活躍物件儲存在老年代,而後存活區就會存現有空餘空間,隨後,伊甸園區將活躍物件儲存在存活區之中,而後在伊甸園區裡為新物件開闢記憶體空間;
  6. 如果這個時候老年代也滿了,那麼這個時候將產生 Major GC(Full GC),進行老年代的記憶體清理;
  7. 如果老年代執行了 Full GC 之後,依然無法進行物件的儲存,就會產生 OOM()異常“OutOfMemoryError”。

面試題:請解釋“StackOverflowError”和“OutOfMemoryError”的區別:

1、stackoverflow: 每當java程式啟動一個新的執行緒時,java虛擬機器會為他分配一個棧,java棧以幀為單位保持執行緒執行狀態;當執行緒呼叫一個方法是,jvm壓入一個新的棧幀到這個執行緒的棧中,只要這個方法還沒返回,這個棧幀就存在。 
如果方法的巢狀呼叫層次太多(如遞迴呼叫),隨著java棧中的幀的增多,最終導致這個執行緒的棧中的所有棧幀的大小的總和大於-Xss設定的值,而產生生StackOverflowError溢位異常。 
2、OutOfMemoryError: 如上。