天天看點

JVM 調優《五》記憶體調優

記憶體調優

          首先需要注意的是在對JVM記憶體調優的時候不能隻看作業系統級别Java程序所占用的記憶體,這個數值不能準确的反應堆記憶體的真實占用情況,因為GC過後這個值是不會變化的,是以記憶體調優的時候要更多地使用JDK提供的記憶體檢視工具,比如JConsole和Java VisualVM。

         對JVM記憶體的系統級的調優主要的目的是減少GC的頻率和Full GC的次數,過多的GC和Full GC是會占用很多的系統資源(主要是CPU),影響系統的吞吐量。特别要關注Full GC,因為它會對整個堆進行整理,導緻Full GC一般由于以下幾種情況:

舊生代空間不足

         調優時盡量讓對象在新生代GC時被回收、讓對象在新生代多存活一段時間和不要建立過大的對象及數組避免直接在舊生代建立對象 

Pemanet Generation空間不足

     增大Perm Gen空間,避免太多靜态對象 

    統計得到的GC後晉升到舊生代的平均大小大于舊生代剩餘空間

    控制好新生代和舊生代的比例 

System.gc()被顯示調用

    垃圾回收不要手動觸發,盡量依靠JVM自身的機制 

    調優手段主要是通過控制堆記憶體的各個部分的比例和GC政策來實作,下面來看看各部分比例不良設定會導緻什麼後果

1新生代設定過小

    一是新生代GC次數非常頻繁,增大系統消耗;二是導緻大對象直接進入舊生代,占據了舊生代剩餘空間,誘發Full GC

2新生代設定過大

    一是新生代設定過大會導緻舊生代過小(堆總量一定),進而誘發Full GC;二是新生代GC耗時大幅度增加

    一般說來新生代占整個堆1/3比較合适

3Survivor設定過小

    導緻對象從eden直接到達舊生代,降低了在新生代的存活時間

4Survivor設定過大

    導緻eden過小,增加了GC頻率

    另外,通過-XX:MaxTenuringThreshold=n來控制新生代存活時間,盡量讓對象在新生代被回收

    由記憶體管理和垃圾回收可知新生代和舊生代都有多種GC政策群組合搭配,選擇這些政策對于我們這些開發人員是個難題,JVM提供兩種較為簡單的GC政策的設定方式

1吞吐量優先

    JVM以吞吐量為名額,自行選擇相應的GC政策及控制新生代與舊生代的大小比例,來達到吞吐量名額。這個值可由-XX:GCTimeRatio=n來設定

2暫停時間優先

    JVM以暫停時間為名額,自行選擇相應的GC政策及控制新生代與舊生代的大小比例,盡量保證每次GC造成的應用停止時間都在指定的數值範圍内完成。這個值可由-XX:MaxGCPauseRatio=n來設定

彙總一下JVM常見配置

堆設定

-Xms:初始堆大小

-Xmx:最大堆大小

-XX:NewSize=n:設定年輕代大小

-XX:NewRatio=n:設定年輕代和年老代的比值。如:為3,表示年輕代與年老代比值為1:3,年輕代占整個年輕代年老代和的1/4

-XX:SurvivorRatio=n:年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區占整個年輕代的1/5

-XX:MaxPermSize=n:設定持久代大小

收集器設定

-XX:+UseSerialGC:設定串行收集器

-XX:+UseParallelGC:設定并行收集器

-XX:+UseParalledlOldGC:設定并行年老代收集器

-XX:+UseConcMarkSweepGC:設定并發收集器

垃圾回收統計資訊

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

并行收集器設定

-XX:ParallelGCThreads=n:設定并行收集器收集時使用的CPU數。并行收集線程數。

-XX:MaxGCPauseMillis=n:設定并行收集最大暫停時間

并發收集器設定

繼續閱讀