JVM堆內存設置和測試


1. Java虛擬機內存結構

划分新生代和老年代,這樣只在新生代分配內存,從而簡化了新對象的分配。另外新生代和老年代使用不同的GC算法,可以更有效的清除不再需要的對象。
從上圖可以看出,JVM內存由young+old+permanent組成,JVM又進一步將Young分成了eden,from survivor和to survivor三個區域。新對象會首先分配在 Eden 中(如果新對象過大,會直接分配在老年代中)。在GC中,Eden 中的對象會被移動到survivor中,直至對象熬過一定的GC的次數,會被移動到老年代。老年代一般是一些系統級(線程庫,classloader等)的對象,官方推薦新生代占堆大小的3/8,而survivor區各占新生代的1/10。

2. GC原理

jvm_mem
很多對象的生存時間都很短,而新生對象很少引用生存時間長的對象。所以,GC會頻繁訪問新生代對象,執行Minor GC。在新生代中,GC可以快速標記回收”死對象”,而不需要掃描整個Heap中的存活一段時間的”老對象”(即執行major/FULL GC)。
新生代的GC使用復制算法。在GC前To survivor區保持清空,對象保存在Eden和From survivor區中,GC運行時,Eden中的幸存對象被復制到 To survivor區。針對 From survivor取中的幸存對象,會考慮對象年齡,如果年齡沒達到閥值(tenuring threshold),對象會被復制到To survivor區。如果達到閥值對象被復制到老年代。復制階段完成后,Eden 和From survivor區中只保存死對象,可以被視為全部清空。如果在復制過程中To survivor區被填滿了,剩余的對象會被復制到老年代中。最后 From和To會對換。
young_gc
上圖演示GC過程,黃色表示死對象,綠色表示剩余空間,紅色表示幸存對象
如果新生代過小,會導致新生對象很快就晉升到老年代中,在老年代中對象很難被回收。如果新生代過大,會發生過多的復制過程。所以需要通過不斷的測試調優,找到一個合適的JVM參數。

3. JVM內存參數

堆內存大小設置

-Xms :初始堆大小。只要啟動,就占用的堆大小
-Xmx :最大堆大小。java.lang.OutOfMemoryError: Java heap這個錯誤可以通過配置-Xms和-Xmx參數來設置
-Xss:棧大小分配。棧是每個線程私有的區域,通常只有幾百K大小,決定了函數調用的深度,而局部變量、參數都分配到棧上。當出現大量局部變量,遞歸時,會發生棧空間OOM(java.lang.StackOverflowError)之類的錯誤。
-XX:NewSize=n :設置新生代大小的絕對值
-XX:NewRatio=n: 設置年輕代和年老代的比值。比如設置為3,則新生代:老年代=1:3,新生代占1/4的總heap大小。
-XX:SurvivorRatio=n :年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有from和to兩個。比如設置為8時,那么eden:from:to=8:1:1
-XX:MaxPermSize=n :設置持久代大小 ;java.lang.OutOfMemoryError: PermGen space這個OOM錯誤需要合理調大PermSize和MaxPermSize大小。
-XX:HeapDumpOnOutOfMemoryError :發生OOM時轉儲堆到文件,這是一個非常好的診斷方法。
-XX:HeapDumpPath :導出堆的轉儲文件路徑
-XX:OnOutOfMemoryError:OOM時,執行一個腳本,比如發送郵件報警,重啟程序。后面跟着一個腳本的路徑。

測試1

第一次分配5M,沒有超過xms。第二次再次分配5M,total mem會增加。第三次再申請40M,超過xmx限制所以報了OOM錯誤。

以50m XMX和10m XMS的運行測試:

 

測試2

 

 

下面按1m的新生代設置,這時對象大於新生代大小,會直接創建在老年代。新生代沒有使用。沒有觸發gc

 

下面按15m的新生代設置,全部分配在eden區,老年代沒有使用,沒有觸發gc。

 

下面按8m的新生代設置,觸發了一次gc,由於from和to的大小小於1M的對象大小,eden區會直接進入老年代。

 

 

下面按7m的新生代設置,from和to的大小可以為1/xmn,大於觸發了3次新生代gc,一共回收了7M左右的空間,最后剩余3M在系統當中,沒有使用老年代。

 

 

新生代占一半大小(10m),幸存區為3:1:1(6m:2m,2m),觸發了1次gc,回收了7m左右空間,沒有使用老年代。對於這種臨時對象,減少老年代的使用是gc優化的關鍵。

 

 

^^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM