概述html
公司的江南白衣寫了一篇關鍵業務系統的JVM參數推薦(2016熱冬版)的文章,大牛的文章老是須要細細品讀。這篇文章介紹大量的JVM調優參數,內容也比較多,本文只是列出我本身能理解的一些參數,暫時理解不了的參數就只能等之後本身實力到家了,再慢慢補充上來。java
性能調優參數算法
JAVA進程啓動的時候,會加載rt.jar這個核心包的,rt.jar包裏的Integer天然也是被加載到JVM中,Integer裏面有一個IntegerCache緩存,以下:緩存
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}複製代碼
IntegerCache有一個靜態代碼塊,JVM在加載Integer這個類時,會優先加載靜態的代碼。當JVM進程啓動完畢後, -128 ~ +127 範圍的數字會被緩存起來,調用valueOf方法的時候,若是是這個範圍內的數字,則直接從緩存取出。
超過這個範圍的,就只能構造新的Integer對象了。bash
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}複製代碼
所以能夠根據實際狀況把AutoBoxCacheMax的值設置的大寫,好比江南白衣推薦的併發
-XX:AutoBoxCacheMax=20000複製代碼
JAVA進程啓動的時候,雖然咱們能夠爲JVM指定合適的內存大小,可是這些內存操做系統並無真正的分配給JVM,而是等JVM訪問這些內存的時候,才真正分配,這樣會形成如下問題。
一、GC的時候,新生代的對象要晉升到老年代的時候,須要內存,這個時候操做系統才真正分配內存,這樣就會加大young gc的停頓時間;
二、可能存在內存碎片的問題。jvm
能夠在JVM啓動的時候,配置性能
-XX:+AlwaysPreTouch複製代碼
參數,這樣JVM就會先訪問全部分配給它的內存,讓操做系統把內存真正的分配給JVM.後續JVM就能夠順暢的訪問內存了。學習
GC參數ui
JAVA 1.7用的垃圾收集算法仍是CMS,下文提到的參數都是針對CMS的。
以前寫過一篇java垃圾回收算法之-CMS(併發標記清除),裏面提到垃圾收集線程會跟應用的線程一塊兒並行的工做,萬一垃圾收集線程在工做的時候,老年代內存不足怎麼辦?所以最好仍是提早啓動CMS來收集垃圾(CMS GC)。
能夠經過設置
CMSInitiatingOccupancyFraction=75複製代碼
那麼當老年代堆空間的使用率達到75%的時候就開始執行垃圾回收,CMSInitiatingOccupancyFraction默認值是92%,這個就太大了。
CMSInitiatingOccupancyFraction參數必須跟下面兩個參數一塊兒使用才能生效的。
-XX:+UseConcMarkSweepGC
-XX:+UseCMSInitiatingOccupancyOnly複製代碼
新生代是使用copy算法來進行垃圾回收的,能夠參看
默認狀況下,當新生代執行了15次young gc後,若是還有對象存活在Survivor區中,那麼就能夠直接將這些對象晉升到老年代,可是因爲新生代使用copy算法,若是Survivor區存活的對象過久的話,Survivor區存活的對象就越多,這個就會影響copy算法的性能,使得young gc停頓的時間加長,建議設置成6。
-XX:MaxTenuringThreshold=6複製代碼
若是系統使用堆外內存,好比用到了Netty的DirectByteBuffer類,那麼當想回收堆外內存的時候,須要調用
System.gc()複製代碼
而這個方法將進行full gc,整個應用將會停頓,若是是使用CMS垃圾收集器,那麼能夠設置
-XX:+ExplicitGCInvokesConcurrent複製代碼
這個參數來改變System.gc()
的行爲,讓其從full gc --> CMS GC,CMS GC是併發收集的,且中間執行的過程當中,只有部分階段須要stop the world。
注意:設置了ExplicitGCInvokesConcurrent,那就不要設置DisableExplicitGC參數來禁掉System.gc()
。
內存參數
這兩個通常都是設置4個g
GC最多的仍是發生在新生代的young gc,因此能夠提升一下新生代在整個堆的佔用比例,建議設置爲對半分,儘可能避免young gc
-XX:NewRatio=1複製代碼
原文連接