1. 程式人生 > >速記JVM記憶體模型和垃圾回收策略

速記JVM記憶體模型和垃圾回收策略

一、常用JVM引數

-Xms: 初始堆大小
-Xmx: 最大堆
-Xss:  棧容量
-PermSize: 方法區大小
-MaxPermSize: 最大方法區大小
-MaxDirectMemorySize:  最大直接記憶體大小

二、java虛擬機器基本結構

 

1.PC暫存器(程式計數器):執行緒私有的,記錄的是正在執行的虛擬機器位元組碼指令的地址。

2.java棧(虛擬機器棧):執行緒私有的,每個方法在執行的同時都會建立一個棧幀,用於儲存區域性變量表、運算元棧、動態連結、方法出口等資訊。方法的呼叫到完成對應入棧到出棧的過程。

3.本地方法棧:執行緒私有的,為native方法服務。

4.java堆:執行緒共享的,用於存放物件例項。從記憶體回收的角度看,分為新生代(eden、from、to)和老年代;從記憶體分配的角度看,java堆中可能劃分出多個執行緒私有的分配緩衝區(TLAB)。

5.方法區(永久代):執行緒共享的,用於儲存類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。GC行為比較少,主要針對常量池的回收和對型別的解除安裝。

5.1 執行時常量池:是方法區的一部分,用於存放編譯期生成的字面量和符號引用。

6.直接記憶體:不受java堆大小的限制,直接申請系統的實體記憶體。

三、垃圾回收策略

主要針對堆區進行回收,方法區收集效率很低。

3.1 垃圾收集演算法

3.1.1 標記-清除演算法

主要用於老年代,首先標記出所有需要回收的物件,然後統一回收。

優點:簡單

缺點:標記和清除的效率都不高,而且會產生大量的記憶體碎片。

3.1.2 複製演算法

將記憶體分為大小相等的兩塊,每次只使用一塊。當這一塊記憶體用完了,就把存活的物件複製到另一塊上,然後清除這一塊。

主要用於新生代,把新生代按8:1:1的比例分,edan區分80%,from存活區和to存活區分10%。回收時,將edan和from(to)中存活的物件一次性複製到to(from)中,然後清理掉,如果存活區空間不足,就分配到老年代。

3.1.3 標記-整理演算法

主要用於老年代,標記過程與“標記-清除”演算法一樣,為解決記憶體碎片的問題,後續步驟不是直接對可回收物件進行清理,而是讓所有存活的物件都像一端移動,然後直接清理掉端邊界以外的記憶體。

3.2 垃圾收集器

3.2.1 Serial(序列)收集器

單執行緒,序列,用於新生代,使用複製演算法,執行在Client模式下。

優點:簡單高效。缺點:它進行垃圾回收時,必須暫停其他所有的工作執行緒,直到收集結束。

3.2.2 Serial Old收集器

單執行緒,序列,用於老年代,使用標記整理演算法,執行在Client模式下。

優點:簡單高效。缺點:它進行垃圾回收時,必須暫停其他所有的工作執行緒,直到收集結束。

如果在Server模式下,它可以和Parallel Scavenge收集器搭配使用;還可以作為CMS收集器的後備預案,在併發收集發生Concurrent Model Failure 時使用。

3.2.3 ParNew收集器

用於新生代,其實就是Serial的多執行緒版本,它第一次實現了讓垃圾收集執行緒和使用者執行緒(基本上)同時工作,執行在Server模式下。但在單CPU環境下不如Serial。

3.2.4 Parallel(並行) Scavenge(打掃)收集器

用於新生代,使用複製演算法,多執行緒,和ParNew類似。但是它的關注點是吞吐量【吞吐量=執行使用者程式碼時間/(執行使用者程式碼時間+垃圾收集時間)】,其他收集器的關注點是縮短垃圾收集時使用者執行緒的停頓時間。-XX:MaxGCPauseMillis控制最大垃圾收集停頓時間,-XX:GCTimeRatio設定吞吐量的大小

3.2.5 Parallel Old收集器

是 Parallel Scavenge收集器的老年代版本,多執行緒,使用“標記-整理”演算法。

在注重吞吐量以及CPU資源敏感的場合,可以優先考慮Parallel Scavenge和Parallel Old搭配使用。

3.2.6 CMS收集器

目的是獲取最短回收停頓時間 ,使用標記-清除演算法。運作過程分為1.初始標記(STW);2.併發標記;3.重新標記(STW);4.併發清除。

優點:併發收集、低停頓

缺點:

1.因為是併發設計的,所以當CPU不足時,效率會不高;

2.由於併發清理階段,使用者執行緒還在產生垃圾,所以在jdk1.5中,CMS在老年代使用了68%時被啟用,jdk1.6中,是92%。要是CMS執行期間記憶體不足,就會出現“Concurrent Mode Failure”失敗,這時虛擬機器會啟用Serial Old來重新收集,這樣停頓時間會更長了。

3. 因為是基於“標記-清除”演算法,會有大量空間碎片。為了解決這個問題,CMS提供了碎片合併整理過程,但停頓時間更長了。

3.2.7 G1收集器

G1是一款面向服務端應用的垃圾收集器。

特點:併發和並行、分代收集、空間整合、可預測的停頓

運作步驟:初始標記、併發標記、最終標記、篩選回收

使用G1時,它將整個java堆劃分為多個大小相等的獨立區域(Region),新生代和老年代不再是物理隔離了,他們都是一部分Region的集合。G1跟蹤各個Region裡面的垃圾堆積的價值大小,優先回收價值最大的Region。