1.1 JDK7及以前的版本
其中最上一層是Nursery內(nèi)存,一個對象被創(chuàng)建以后首先被放到Nursery中的Eden內(nèi)
存中,,如果存活期超兩個Survivor之后就會被轉(zhuǎn)移到長時內(nèi)存中(Old Generation)中,。
永久內(nèi)存中存放著對象的方法、變量等元數(shù)據(jù)信息,。通過如果永久內(nèi)存不夠,,就會得到如下錯誤:
Java.lang.OutOfMemoryError: PermGen
1.2 JDK8版本
JDK8中把存放元數(shù)據(jù)中的永久內(nèi)存從堆內(nèi)存中移到了本地內(nèi)存(native memory)中,這樣永久內(nèi)存就不再占用堆內(nèi)存,,它可以通過自動增長來避免JDK7以及前期版本中常見的永久內(nèi)存錯誤(java.lang.OutOfMemoryError: PermGen),。
JDK8也提供了一個新的設(shè)置Matespace內(nèi)存大小的參數(shù):
-XX:MaxMetaspaceSize=128m
注意:如果不設(shè)置JVM將會根據(jù)一定的策略自動增加本地元內(nèi)存空間。如果你設(shè)置的元內(nèi)存空間過小,,你的應(yīng)用程序可能得到以下錯誤:
java.lang.OutOfMemoryError: Metadata space
2. JVM參數(shù)
-XX 參數(shù)被稱為不穩(wěn)定參數(shù),,此類參數(shù)的設(shè)置很容易引起JVM性能上的差異。
不穩(wěn)定參數(shù)語法規(guī)則:
布爾類型
-XX:+<option> '+'表示啟用該選項
-XX:-<option> '-'表示關(guān)閉該選項
數(shù)字類型
-XX:<option>=<number>
# 可跟隨單位,,例如:'m'或'M'表示兆字節(jié);'k'或'K'千字節(jié);'g'或'G'千兆字節(jié),。32K與32768是相同大小的。
字符串類型
-XX:<option>=<string>
# 通常用于指定一個文件,、路徑或一系列命令列表,。例如:-XX:HeapDumpPath=./dump.core
2.1 行為選項
選項 |
默認(rèn)值 |
描述 |
-XX:-AllowUserSignalHandlers |
限于Linux和Solaris默認(rèn)關(guān)閉 |
允許為java進(jìn)程安裝信號處理器。 |
-XX:AltStackSize=16384 |
僅適用于Solaris,,從5.0中刪除 |
備用信號堆棧大小(以字節(jié)為單位) |
-XX:-DisableExplicitGC |
默認(rèn)關(guān)閉 |
禁止在運行期顯式地調(diào)用 System.gc(),。 注意:你熟悉的代碼里沒調(diào)用System.gc(),,不代表你依賴的框架工具沒在使用。 |
-XX:+FailOverToOldVerifier |
Java6新引入選項,,默認(rèn)啟用 |
如果新的Class校驗器檢查失敗,,則使用老的校驗器。解決兼容性問題,。 關(guān)聯(lián)選項:-XX:+UseSplitVerifier |
-XX:+HandlePromotionFailure |
Java1.5以前默認(rèn)關(guān)閉 Java1.6后默認(rèn)啟用 |
新生代收集擔(dān)保,,于年老代預(yù)留內(nèi)存。 |
-XX:+MaxFDLimit |
限于Solaris 默認(rèn)啟用 |
設(shè)置java進(jìn)程可用文件描述符為操作系統(tǒng)允許的最大值,。 |
-XX:PreBlockSpin |
默認(rèn)10 |
控制多線程自旋鎖優(yōu)化的自旋次數(shù)
前置選項: -XX:+UseSpinning |
-XX:-RelaxAccessControlCheck |
默認(rèn)關(guān)閉 Java1.6引入 |
在Class校驗器中,,放松對訪問控制的檢查。 作用與reflection里的setAccessible類似,。 |
-XX:+ScavengeBeforeFullGC |
默認(rèn)啟用 |
在Full GC前觸發(fā)一次Minor GC |
-XX:+UseAltSigs |
限于Solaris 默認(rèn)啟用 |
為了防止與其他發(fā)送信號的應(yīng)用程序沖突,,允許使用候補(bǔ)信號替代 SIGUSR1和SIGUSR2。 |
-XX:+UseBoundThreads |
限于Solaris 默認(rèn)啟用 |
綁定所有的用戶線程到內(nèi)核線程。 減少線程進(jìn)入饑餓狀態(tài)(得不到任何cpu time)的次數(shù),。 |
-XX:-UseConcMarkSweepGC |
默認(rèn)關(guān)閉 Java1.4引入 |
啟用CMS低停頓垃圾收集器,。 |
-XX:+UseGCOverheadLimit |
默認(rèn)啟用 Java1.6引入 |
限制GC的運行時間。如果GC耗時過長,,就拋OutOfMemoryError,。 |
-XX:+UseLWPSynchronization |
限于solaris, 默認(rèn)啟用, Java1.4引入 |
使用輕量級進(jìn)程(內(nèi)核線程)替換線程同步。 |
-XX:-UseParallelGC |
-server時啟用, 其他情況下:默認(rèn)關(guān)閉, Java1.4引入 |
為新生代使用并行清除,,年老代使用單線程Mark-Sweep-Compact的垃圾收集器,。 |
-XX:-UseParallelOldGC |
默認(rèn)關(guān)閉, Java1.5引入 |
為老年代和新生代都使用并行清除的垃圾收集器。開啟此選項將自動開啟-XX:+UseParallelGC 選項 |
-XX:-UseSerialGC |
-client時啟用, 默認(rèn)關(guān)閉, Java1.5引入 |
使用串行垃圾收集器,。 |
-XX:-UseSpinning |
Java1.4.2和1.5需要手動啟用, Java1.6默認(rèn)已啟用 |
啟用多線程自旋鎖優(yōu)化,。
關(guān)聯(lián)選項: -XX:PreBlockSpin=10 |
-XX:+UseTLAB |
Java1.4.2以前和使用-client選項時:默認(rèn)關(guān)閉, 其余版本默認(rèn)啟用 |
啟用線程本地緩存區(qū)(Thread Local) |
-XX:+UseSplitVerifier |
Java1.5默認(rèn)關(guān)閉, Java1.6默認(rèn)啟用 |
使用新的Class類型校驗器 。
關(guān)聯(lián)選項: -XX:+FailOverToOldVerifier |
-XX:+UseThreadPriorities |
默認(rèn)啟用 |
使用本地線程的優(yōu)先級,。 |
-XX:+UseVMInterruptibleIO |
限于solaris, 默認(rèn)啟用, Java1.6引入 |
在solaris中,,允許運行時中斷線程。 |
2.2 性能選項
選項 |
默認(rèn)值 |
描述 |
-XX:+AggressiveOpts |
Java1.5 引入 默認(rèn)關(guān)閉 Java1.6后默認(rèn)開啟 |
開啟編譯器性能優(yōu)化,。 |
-XX:CompileThreshold=10000 |
默認(rèn)值:1000 |
通過JIT編譯器,,將方法編譯成機(jī)器碼的觸發(fā)閥值,可以理解為調(diào)用方法的次數(shù),,例如調(diào)1000次,,將方法編譯為機(jī)器碼。 [-client: 1,500] |
-XX:LargePageSizeInBytes=4m |
默認(rèn)值:4m amd64位:2m |
設(shè)置堆內(nèi)存的內(nèi)存最大值,。 |
-XX:MaxHeapFreeRatio=70 |
默認(rèn)70 |
GC后,,如果發(fā)現(xiàn)空閑堆內(nèi)存占到整個預(yù)估上限值的70%,則收縮預(yù)估上限值,。 |
-XX:MaxNewSize=size |
1.3.1 Sparc: 32m 1.3.1 x86: 2.5m |
新生代占整個堆內(nèi)存的最大值,。從Java1.4開始, MaxNewSize成為 NewRatio的一個函數(shù) |
-XX:MaxPermSize=64m |
Java1.5以后::64 bit VMs會增大預(yù)設(shè)值的30% 1.4 amd64::96m 1.3.1 -client: 32m 其他默認(rèn) 64m |
Perm(俗稱方法區(qū))占整個堆內(nèi)存的最大值。 |
-XX:MinHeapFreeRatio=40 |
默認(rèn)值:40 |
GC后,,如果發(fā)現(xiàn)空閑堆內(nèi)存占到整個預(yù)估上限值的40%,,則增大上限值。 關(guān)聯(lián)選項: -XX:MaxHeapFreeRatio=70 |
-XX:NewRatio=2 |
Sparc -client: 8 x86 -server: 8 x86 -client: 12 -client: 4 (1.3) 8 (1.3.1+) x86: 12 其他:2 |
新生代和年老代的堆內(nèi)存占用比例,。 例如2表示新生代占年老代的1/2,,占整個堆內(nèi)存的1/3。 |
-XX:NewSize=2m |
5.0以后: 64 bit Vms 會增大預(yù)設(shè)值的30% x86: 1m x86, 5.0以后: 640k 其他:2.125m |
新生代預(yù)估上限的默認(rèn)值,。 |
-XX:ReservedCodeCacheSize=32m |
Solaris 64-bit, amd64, -server x86: 48m 1.5.0_06之前, Solaris 64-bit amd64: 1024m 其他:32m |
設(shè)置代碼緩存的最大值,,編譯時用。 |
-XX:SurvivorRatio=8 |
Solaris amd64: 6 Sparc in 1.3.1: 25 Solaris platforms 5.0以前: 32 其他:8 |
Eden與Survivor的占用比例,。例如8表示,,一個survivor區(qū)占用 1/8 的Eden內(nèi)存,,即1/10的新生代內(nèi)存,為什么不是1/9,? 因為我們的新生代有2個survivor,,即S1和S22。所以survivor總共是占用新生代內(nèi)存的 2/10,,Eden與新生代的占比則為 8/10,。 |
-XX:TargetSurvivorRatio=50 |
默認(rèn)值:50 |
實際使用的survivor空間大小占比。默認(rèn)是47%,,最高90%,。 |
-XX:ThreadStackSize=512 |
Sparc: 512 Solaris x86: 320 (5.0以前 256) Sparc 64 bit: 1024 Linux amd64: 1024 (5.0 以前 0) 其他:512. |
線程堆棧大小 |
-XX:+UseBiasedLocking |
Java1.5 update 6后引入 默認(rèn)關(guān)閉。 Java1.6默認(rèn)啟用,。 |
啟用偏向鎖 |
-XX:+UseFastAccessorMethods |
默認(rèn)啟用 |
優(yōu)化原始類型的getter方法性能,。 |
-XX:-UseISM |
默認(rèn)啟用 |
啟用solaris的ISM |
-XX:+UseLargePages |
Java1.5 update 5后引入 默認(rèn)關(guān)閉 Java1.6默認(rèn)啟用 |
啟用大內(nèi)存分頁。
關(guān)聯(lián)選項: -XX:LargePageSizeInBytes=4m |
-XX:+UseMPSS |
Java1.4.1 之前默認(rèn)關(guān)閉 其他版本默認(rèn)啟用 |
啟用solaris的MPSS,,不能與ISM同時使用,。 |
-XX:+UseStringCache |
默認(rèn)開啟 |
緩存常用字符串。 |
-XX:AllocatePrefetchLines=1 |
默認(rèn)值:1 |
在使用JIT生成的預(yù)讀取指令分配對象后讀取的緩存行數(shù),。如果上次分配的對象是一個實例則默認(rèn)值是1,,如果是一個數(shù)組則是3 |
-XX:AllocatePrefetchStyle=1 |
默認(rèn)值:1 |
預(yù)讀取指令的生成代碼風(fēng)格 0- 無預(yù)讀取指令生成 1-在每次分配后執(zhí)行預(yù)讀取命令 2-當(dāng)預(yù)讀取指令執(zhí)行后使用TLAB()分配水印指針來找回入口 |
-XX:+UseCompressedStrings |
Java1.6 update 21引入 |
其中,對于不需要16位字符的字符串,,可以使用byte[] 而非char[],。對于許多應(yīng)用,這可以節(jié)省內(nèi)存,,但速度較慢(5%-10%) |
-XX:+OptimizeStringConcat |
Java1.6 update 20引入 |
在可能的情況下優(yōu)化字符串連接操作,。 |
2.3 調(diào)試選項
選項 |
默認(rèn)值 |
描述 |
-XX:-CITime |
默認(rèn)啟用 |
打印JIT編譯器編譯耗時。 |
-XX:ErrorFile=./hs_err_pid.log |
Java1.6引入 |
如果JVM crashed,,將錯誤日志輸出到指定文件路徑,。 |
-XX:-ExtendedDTraceProbes |
Java6引入,限于solaris 默認(rèn)關(guān)閉 |
啟用dtrace診斷 |
-XX:HeapDumpPath=./java_pid.hprof |
默認(rèn)是java進(jìn)程啟動位置 |
堆內(nèi)存快照的存儲文件路徑,。 |
-XX:-HeapDumpOnOutOfMemoryError |
默認(rèn)關(guān)閉 |
在java.lang.OutOfMemoryError 異常出現(xiàn)時,,輸出一個dump.core文件,,記錄當(dāng)時的堆內(nèi)存快照(見 -XX:HeapDumpPath 的描述) |
-XX:OnError=”\;\” |
Java1.4引入 |
當(dāng)java每拋出一個ERROR時,,運行指定命令行指令集。指令集是與OS環(huán)境相關(guān)的,,在Linux下多數(shù)是.sh腳本,,windows下是.bat批處理。 |
-XX:OnOutOfMemoryError=”\;\” |
Java1.4.2 update 12和Java6時引入 |
當(dāng)?shù)谝淮伟l(fā)生java.lang.OutOfMemoryError 時,,運行指定命令行指令集,。指令集是與OS環(huán)境相關(guān)的,,在linux下多數(shù)是.sh腳本,windows下是.bat批處理,。 |
-XX:-PrintClassHistogram |
默認(rèn)關(guān)閉 |
在Windows下, 按ctrl-break或Linux下是執(zhí)行kill -3(發(fā)送SIGQUIT信號)時,,打印class柱狀圖。 jmap -histo pid也實現(xiàn)了相同的功能,。 |
-XX:-PrintConcurrentLocks |
默認(rèn)關(guān)閉 |
在thread dump的同時,,打印java.util.concurrent的鎖狀態(tài)。 jstack -l pid 也同樣實現(xiàn)了同樣的功能,。 |
-XX:-PrintCommandLineFlags |
Java1.5 引入,,默認(rèn)關(guān)閉 |
Java啟動時,往stdout打印當(dāng)前啟用的非穩(wěn)態(tài)jvm options,。 例如: -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+DoEscapeAnalysis |
-XX:-PrintCompilation |
默認(rèn)關(guān)閉 |
往stdout打印方法被JIT編譯時的信息,。 |
-XX:-PrintGC |
默認(rèn)關(guān)閉 |
開啟GC日志打印。 顯示結(jié)果例如: [Full GC 131115K->7482K(1015808K), 0.1633180 secs] 該選項可通過 com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 動態(tài)啟用,。 |
-XX:-PrintGCDetails |
Java1.4引入,,默認(rèn)關(guān)閉 |
打印GC回收的詳細(xì)信息。 顯示結(jié)果例如: [Full GC (System) [Tenured: 0K->2394K(466048K), 0.0624140 secs] 30822K->2394K(518464K), [Perm : 10443K->10443K(16384K)], 0.0625410 secs] [Times: user=0.05 sys=0.01, real=0.06 secs] 該選項可通過 com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 動態(tài)啟用,。 |
-XX:-PrintGCTimeStamps |
默認(rèn)關(guān)閉 |
打印GC停頓耗時,。 顯示結(jié)果例如: 2.744: [Full GC (System) 2.744: [Tenured: 0K->2441K(466048K), 0.0598400 secs] 31754K->2441K(518464K), [Perm : 10717K->10717K(16384K)], 0.0599570 secs] [Times: user=0.06 sys=0.00, real=0.06 secs] 該選項可通過 com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 動態(tài)啟用。 |
-XX:-PrintTenuringDistribution |
默認(rèn)關(guān)閉 |
打印對象的存活期限信息,。 顯示結(jié)果例如: [GC Desired survivor size 4653056 bytes, new threshold 32 (max 32) - age 1: 2330640 bytes, 2330640 total - age 2: 9520 bytes, 2340160 total 204009K->21850K(515200K), 0.1563482 secs] Age1,2表示在第1和2次GC后存活的對象大小,。 |
-XX:-TraceClassLoading |
默認(rèn)關(guān)閉 |
打印class裝載信息到stdout。記Loaded狀態(tài),。 例如: [Loaded java.lang.Object from /opt/taobao/install/jdk1.6.0_07/jre/lib/rt.jar] |
-XX:-TraceClassLoadingPreorder |
1.4.2引入,,默認(rèn)關(guān)閉 |
按class的引用/依賴順序打印類裝載信息到stdout。不同于 TraceClassLoading,,本選項只記 Loading狀態(tài),。 例如: [Loading java.lang.Object from /home/confsrv/jdk1.6.0_14/jre/lib/rt.jar] |
-XX:-TraceClassResolution |
1.4.2引入,默認(rèn)關(guān)閉 |
打印所有靜態(tài)類,,常量的代碼引用位置,。用于debug。 例如: RESOLVE java.util.HashMap java.util.HashMapEntryHashMap.java:209<br>說明HashMap類的209行引用了靜態(tài)類java.util.HashMapEntry |
-XX:-TraceClassUnloading |
默認(rèn)關(guān)閉 |
打印class的卸載信息到stdout,。記Unloaded狀態(tài),。 |
-XX:-TraceLoaderConstraints |
Java1.6 引入,默認(rèn)關(guān)閉 |
打印class的裝載策略變化信息到stdout,。 裝載策略變化是實現(xiàn)classloader隔離/名稱空間一致性的關(guān)鍵技術(shù),。 |
-XX:+PerfSaveDataToFile |
默認(rèn)啟用 |
當(dāng)java進(jìn)程因java.lang.OutOfMemoryError 異常或crashed 被強(qiáng)制終止后,,生成一個堆快照文件,。 |
-XX:ParallelGCThreads=n |
默認(rèn)值:隨JVM運行平臺不同而異 |
配置并行收集器的線程數(shù),,即:同時多少個線程一起進(jìn)行垃圾回收。此值最好配置與處理器數(shù)目相等,。 |
-XX:+UseCompressedOops |
32位默認(rèn)關(guān)閉,,64位默認(rèn)啟動 |
使用compressed pointers。這個參數(shù)默認(rèn)在64bit的環(huán)境下默認(rèn)啟動,,但是如果JVM的內(nèi)存達(dá)到32G后,,這個參數(shù)就會默認(rèn)為不啟動,因為32G內(nèi)存后,,壓縮就沒有多大必要了,,要管理那么大的內(nèi)存指針也需要很大的寬度了 |
-XX:+AlwaysPreTouch |
默認(rèn)關(guān)閉 |
在JVM 初始化時預(yù)先對Java堆進(jìn)行摸底。 |
-XX:AllocatePrefetchDistance=n |
默認(rèn)值取決于當(dāng)前JVM 設(shè)置 |
為對象分配設(shè)置預(yù)取距離,。 |
-XX:InlineSmallCode=n |
默認(rèn)值取決于當(dāng)前JVM 設(shè)置 |
當(dāng)編譯的代碼小于指定的值時,內(nèi)聯(lián)編譯的代碼,。 |
-XX:MaxInlineSize=35 |
默認(rèn)值:35 |
內(nèi)聯(lián)方法的最大字節(jié)數(shù)。 |
-XX:FreqInlineSize=n |
默認(rèn)值取決于當(dāng)前JVM 設(shè)置 |
內(nèi)聯(lián)頻繁執(zhí)行的方法的最大字節(jié)碼大小,。 |
-XX:LoopUnrollLimit=n |
默認(rèn)值取決于當(dāng)前JVM 設(shè)置 |
代表節(jié)點數(shù)目小于給定值時打開循環(huán)體,。 |
-XX:InitialTenuringThreshold=7 |
默認(rèn)值:7 |
設(shè)置初始的對象在新生代中最大存活次數(shù)。 |
-XX:MaxTenuringThreshold=n |
默認(rèn)值:15,,最大值:15 |
設(shè)置對象在新生代中最大的存活次數(shù),,最大值15,并行回收機(jī)制默認(rèn)為15,,CMS默認(rèn)為4,。 |
-Xloggc: |
默認(rèn)關(guān)閉 |
輸出GC 詳細(xì)日志信息至指定文件。 |
-XX:-UseGCLogFileRotation |
默認(rèn)關(guān)閉 |
開啟GC 日志文件切分功能,,前置選項 -Xloggc |
-XX:NumberOfGClogFiles=1 |
必須>=1,,默認(rèn)值:1 |
設(shè)置切分GC 日志文件數(shù)量,文件命名格式:.0, .1, …, .n-1 |
-XX:GCLogFileSize=8K |
必須>=8K,,默認(rèn)值:8K |
GC日志文件切分大小,。 |
3. 垃圾收集器
3.1 串行回收器
3.1.1 新生代串行回收器
特點
- 它僅僅使用單線程進(jìn)行垃圾回收
- 它是獨占式的垃圾回收
- 進(jìn)行垃圾回收時, Java應(yīng)用程序中的線程都需要暫停(Stop-The-World)
- 使用復(fù)制算法
- 適合CPU等硬件不是很好的場合
設(shè)置參數(shù)
-XX:+UseSerialGC 指定新生使用新生代串行收集器和老年代串行收集器, 當(dāng)以client模式運行時, 它是默認(rèn)的垃圾收集器
3.1.2 老年代串行回收器
特點
- 同新生代串行回收器一樣, 單線程, 獨占式的垃圾回收器
- 通常老年代垃圾回收比新生代回收要更長時間, 所以可能會使應(yīng)用程序停頓較長時間
設(shè)置參數(shù)
-XX:+UseSerialGC 新生代, 老年代都使用串行回收器
-XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器
-XX:+UseParallelGC 新生代使用ParallelGC回收器, 老年代使用串行回收器
3.2 并行回收器
3.2.1 新生代ParNew回收器
特點
- 將串行回收多線程化
- 使用復(fù)制算法
- 垃圾回收時, 應(yīng)用程序仍會暫停, 只不過由于是多線程回收, 在多核CPU上,回收效率會高于串行回收器, 反之在單核CPU,, 效率會不如串行回收器
設(shè)置參數(shù)
-XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器
-XX:+UseConcMarkSweepGC 新生代使用ParNew回收器, 老年代使用CMS回收器
-XX:ParallelGCThreads=n 指回ParNew回收器工作時的線程數(shù)量, cpu核數(shù)小時8時, 其值等于cpu數(shù)量, 高于8時,可以使用公式(3+((5*CPU_count)/8))
3.2.2 新生代ParallelGC回收器
特點
- 同ParNew回收器一樣,, 不同的地方在于,它非常關(guān)注系統(tǒng)的吞吐量(通過參數(shù)控制)
- 使用復(fù)制算法
- 支持自適應(yīng)的GC調(diào)節(jié)策略
設(shè)置參數(shù)
-XX:+UseParallelGC 新生代用ParallelGC回收器, 老年代使用串行回收器
-XX:+UseParallelOldGC 新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器系統(tǒng)吞吐量的控制:
-XX:MaxGCPauseMillis=n(單位ms) 設(shè)置垃圾回收的最大停頓時間,
-XX:GCTimeRatio=n(n在0-100之間) 設(shè)置吞吐量的大小, 假設(shè)值為n, 那系統(tǒng)將花費不超過1/(n+1)的時間用于垃圾回收
-XX:+UseAdaptiveSizePolicy 打開自適應(yīng)GC策略, 在這種模式下, 新生代的大小, eden,survivior的比例, 晉升老年代的對象年齡等參數(shù)會被自動調(diào)整,以達(dá)到堆大小, 吞吐量, 停頓時間之間的平衡點
3.2.3 老年代ParallelOldGC回收器
特點
- 同新生代的ParallelGC回收器一樣, 是屬于老年代的關(guān)注吞吐量的多線程并發(fā)回收器
- 使用標(biāo)記壓縮算法
設(shè)置參數(shù)
-XX:+UseParallelOldGC 新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器, 是非常關(guān)注系統(tǒng)吞吐量的回收器組合, 適合用于對吞吐量要求較高的系統(tǒng)
-XX:ParallelGCThreads=n 指回ParNew回收器工作時的線程數(shù)量, cpu核數(shù)小時8時, 其值等于cpu數(shù)量, 高于8時, 可以使用公式(3+((5*CPU_count)/8))
3.3 CMS回收器(Concurrent Mark Sweep,,并發(fā)標(biāo)記清除)
3.3.1 老年代的并發(fā)回收器
特點
- 是并發(fā)回收, 非獨占式的回收器, 大部分時候應(yīng)用程序不會停止運行
- 針對年老代的回收器
- 使用并發(fā)標(biāo)記清除算法, 因此回收后會有內(nèi)存碎片, 可以使參數(shù)設(shè)置進(jìn)行內(nèi)存碎片的壓縮整理
- 與ParallelGC和ParallelOldGC不同, CMS主要關(guān)注系統(tǒng)停頓時間
主要步驟
- 初始標(biāo)記
- 并發(fā)標(biāo)記
- 預(yù)清理
- 重新標(biāo)記
- 并發(fā)清理
- 并發(fā)重置
注:初始標(biāo)記與重新標(biāo)記是獨占系統(tǒng)資源的,,不能與用戶線程一起執(zhí)行,而其它階段則可以與用戶線程一起執(zhí)行
設(shè)置參數(shù)
-XX:-CMSPrecleaningEnabled 關(guān)閉預(yù)清理, 不進(jìn)行預(yù)清理, 默認(rèn)在并發(fā)標(biāo)記后, 會有一個預(yù)清理的操作,,可減少停頓時間
-XX:+UseConcMarkSweepGC 老年代使用CMS回收器, 新生代使用ParNew回收器
-XX:ConcGCThreads=n 設(shè)置并發(fā)線程數(shù)量,
-XX:ParallelCMSThreads=n 同上, 設(shè)置并發(fā)線程數(shù)量,
-XX:CMSInitiatingOccupancyFraction=n 指定老年代回收閥值, 即當(dāng)老年代內(nèi)存使用率達(dá)到這個值時, 會執(zhí)行一次CMS回收,,默認(rèn)值為68, 設(shè)置技巧: (Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100)>=Xmn
-XX:+UseCMSCompactAtFullCollection 開啟內(nèi)存碎片的整理, 即當(dāng)CMS垃圾回收完成后, 進(jìn)行一次內(nèi)存碎片整理, 要注意內(nèi)存碎片的整理并不是并發(fā)進(jìn)行的, 因此可能會引起程序停頓
-XX:CMSFullGCsBeforeCompation=n 用于指定進(jìn)行多少次CMS回收后,, 再進(jìn)行一次內(nèi)存壓縮
-XX:+CMSParallelRemarkEnabled 在使用UseParNewGC 的情況下, 盡量減少 mark 的時間
-XX:+UseCMSInitiatingOccupancyOnly 表示只有達(dá)到閥值時才進(jìn)行CMS回收
-XX:+CMSConcurrentMTEnabled 當(dāng)該標(biāo)志被啟用時,,并發(fā)的CMS階段將以多線程執(zhí)行,,默認(rèn)開啟
-XX:+CMSIncrementalMode 在增量模式下,CMS 收集器在并發(fā)階段,,不會獨占整個周期,,
而會周期性的暫停,喚醒應(yīng)用線程,。收集器把并發(fā)階段工作,,劃分為片段,安排在次級(minor) 回收之間運行,。這對需要低延遲,,運行在少量CPU服務(wù)器上的應(yīng)用很有用。
3.3.2 Class的回收(永久區(qū)的回收)
設(shè)置參數(shù)
-XX:+CMSClassUnloadingEnabled 開啟回收Perm區(qū)的內(nèi)存, 默認(rèn)情況下, 是需要觸發(fā)一次FullGC
-XX:CMSInitiatingPermOccupancyFraction=n 當(dāng)永久區(qū)占用率達(dá)到這個n值時,,啟動CMS回收, 需上一個參數(shù)開啟的情況下使用
3.4 G1回收器(jdk1.7后全新的回收器, 用于取代CMS)
3.4.1 概述
特點
- 獨特的垃圾回收策略, 屬于分代垃圾回收器
- 使用分區(qū)算法, 不要求eden, 年輕代或老年代的空間都連續(xù)
- 并行性: 回收期間, 可由多個線程同時工作, 有效利用多核cpu資源
- 并發(fā)性: 與應(yīng)用程序可交替執(zhí)行, 部分工作可以和應(yīng)用程序同時執(zhí)行
- 分代GC: 分代收集器, 同時兼顧年輕代和老年代
- 空間整理: 回收過程中, 會進(jìn)行適當(dāng)對象移動, 減少空間碎片
- 可預(yù)見性: G1可選取部分區(qū)域進(jìn)行回收, 可以縮小回收范圍, 減少全局停頓
主要步驟
- 新生代GC
并發(fā)標(biāo)記周期
初始標(biāo)記新生代GC(此時是并行, 應(yīng)用程序會暫停止)–>根區(qū)域掃描–>并發(fā)標(biāo)記–>重新標(biāo)記(此時是并行, 應(yīng)用程序會暫停止)–>獨占清理(此時應(yīng)用程序會暫停止)–>并發(fā)清理
混合回收
這個階段即會執(zhí)行正常的年輕代gc, 也會選取一些被標(biāo)記的老年代區(qū)域進(jìn)行回收, 同時處理新生代和年老輕
若需要, 會進(jìn)行FullGC
混合GC時發(fā)生空間不足
在新生代GC時, survivor區(qū)和老年代無法容納幸存對象時
以上兩者都會導(dǎo)致一次FullGC產(chǎn)生
設(shè)置參數(shù)
-XX:+UseG1GC 打開G1收集器開關(guān),,
-XX:MaxGCPauseMillis=n 指定目標(biāo)的最大停頓時間,任何一次停頓時間超過這個值, G1就會嘗試調(diào)整新生代和老年代的比例, 調(diào)整堆大小, 調(diào)整晉升年齡
-XX:ParallelGCThreads=n 用于設(shè)置并行回收時, GC的工作線程數(shù)量
-XX:InitiatingHeapOccpancyPercent=n 指定整個堆的使用率達(dá)到多少時, 執(zhí)行一次并發(fā)標(biāo)記周期, 默認(rèn)45,, 過大會導(dǎo)致并發(fā)標(biāo)記周期遲遲不能啟動, 增加FullGC的可能, 過小會導(dǎo)致GC頻繁, 會導(dǎo)致應(yīng)用程序性能有所下降
3.4.2 參數(shù)選項
選項 |
默認(rèn)值 |
描述 |
-XX:+UseG1GC |
默認(rèn)關(guān)閉 |
使用G1垃圾處理器 |
-XX:MaxGCPauseMillis=n |
默認(rèn)值:4294967295 |
設(shè)置并行收集最大暫停時間,,這是一個理想目標(biāo),JVM將盡最大努力來實現(xiàn)它,。 |
-XX:InitiatingHeapOccupancyPercent=n |
默認(rèn)值:45 |
啟動一個并發(fā)垃圾收集周期所需要達(dá)到的整堆占用比例,。這個比例是指整個堆的占用比例而不是某一個代(例如G1),如果這個值是0則代表‘持續(xù)做GC’。默認(rèn)值是45 |
-XX:NewRatio=n |
默認(rèn)值:2 |
設(shè)置年輕代和年老代的比值,。例如:值為3,,則表示年輕代與年老代比值為1:3,年輕代占整個年輕代年老代和的1/4,。 |
-XX:SurvivorRatio=n |
默認(rèn)值:8 |
年輕代中Eden區(qū)與兩個Survivor區(qū)的比值,。注意Survivor區(qū)有兩個。如:3,,表示Eden:Survivor=3:2,,一個Survivor區(qū)占整個年輕代的1/5 |
-XX:MaxTenuringThreshold=n |
默認(rèn)值:15 |
設(shè)置垃圾最大存活閥值。如果設(shè)置為0的話,,則年輕代對象不經(jīng)過Survivor區(qū),,直接進(jìn)入年老代。對于年老代比較多的應(yīng)用,,可以提高效率,。如果將此值設(shè)置為一個較大值,則年輕代對象會在Survivor區(qū)進(jìn)行多次復(fù)制,,這樣可以增加對象再年輕代的存活時間,,增加在年輕代即被回收的概論。 |
-XX:ParallelGCThreads=n |
默認(rèn)值:隨JVM運行平臺不同而異 |
配置并行收集器的線程數(shù),,即:同時多少個線程一起進(jìn)行垃圾回收,。此值最好配置與處理器數(shù)目相等,。 |
-XX:ConcGCThreads=n |
默認(rèn)值:隨JVM運行平臺不同而異 |
并行垃圾收集時,使用的線程數(shù),。默認(rèn)值和JVM運行的平臺有關(guān),。 |
-XX:G1ReservePercent=n |
默認(rèn)值:10 |
設(shè)置保留用來做假天花板以減少晉升(新生代對象晉升到老生代)失敗可能性的堆數(shù)目。 |
-XX:G1HeapRegionSize=n |
默認(rèn)值根據(jù)堆大小而定 |
使用G1垃圾回收器,,java堆被劃分成統(tǒng)一大小的區(qū)塊,。這個選項設(shè)置每個區(qū)塊的大小。最小值是1Mb,,最大值是32Mb,。 |
3.4.3 其他GC相關(guān)的設(shè)置
System.gc()
(1)禁用System.gc()
-XX:+DisableExplicitGC 禁止程序中調(diào)用System.gc(), 加了此參數(shù), 程序若有調(diào)用, 返回的空函數(shù)調(diào)用
System.gc()的調(diào)用, 會使用FullGC的方式回收整個堆而會忽略CMS或G1等相關(guān)回收器
(2)System.gc()使用并發(fā)回收
-XX:+ExplicitGCCinvokesConcurrent 使用并發(fā)方式處理顯示的gc, 即開啟后, System.gc()這種顯示GC才會并發(fā)的回收, (CMS, G1)
并行GC前額外觸發(fā)的新生代GC
(1)使用并行回收器(UseParallelGC或者UseParallelOldGC)時, 會額外先觸發(fā)一個新生代GC, 目的是盡可能減少停頓時間
(2)若不需要這種特性, 可以使用以下參數(shù)去除
-XX:-ScavengeBeforeFullGC 即去除在FullGC之前的那次新生代GC, 原本默認(rèn)值為true
對象何時進(jìn)入老年代
(1)當(dāng)對象首次創(chuàng)建時, 會放在新生代的eden區(qū), 若沒有GC的介入,,會一直在eden區(qū), GC后,,是可能進(jìn)入survivor區(qū)或者年老代
(2)當(dāng)對象年齡達(dá)到一定的大小 ,就會離開年輕代, 進(jìn)入老年代,, 對象進(jìn)入老年代的事件稱為晉升, 而對象的年齡是由GC的次數(shù)決定的, 每一次GC,,若對象沒有被回收, 則對象的年齡就會加1, 可以使用以下參數(shù)來控制新生代對象的最大年齡:
-XX:MaxTenuringThreshold=n 假設(shè)值為n , 則新生代的對象最多經(jīng)歷n次GC,, 就能晉升到老年代, 但這個必不是晉升的必要條件
-XX:TargetSurvivorRatio=n 用于設(shè)置Survivor區(qū)的目標(biāo)使用率,,即當(dāng)survivor區(qū)GC后使用率超過這個值, 就可能會使用較小的年齡作為晉升年齡
(3)除年齡外, 對象體積也會影響對象的晉升的, 若對象體積太大, 新生代無法容納這個對象, 則這個對象可能就會直接晉升至老年代, 可通過以下參數(shù)使用對象直接晉升至老年代的閾值, 單位是byte
-XX:PretenureSizeThreshold 即對象的大小大于此值, 就會繞過新生代, 直接在老年代分配, 此參數(shù)只對串行回收器以及ParNew回收有效, 而對ParallelGC回收器無效
在TLAB上分配對象(Thread Local Allocation Buffer, 線程本地分配緩存)
(1)TLAB: TLAB是一個線程專用的內(nèi)存分配區(qū)域, 虛擬機(jī)為線程分配空間, 針對于體積不大的對象, 會優(yōu)先使用TLAB, 這個可以加速對象的分配, TLAB是默認(rèn)開啟的, 若要關(guān)閉可以使用以下參數(shù)關(guān)閉
-XX:-UseTLAB 關(guān)閉TLAB
-XX:+UseTLAB 開啟TLAB, 默認(rèn)也是開啟的
-XX:+PrintTLAB 觀察TALB的使用情況
-XX:TLABRefillWasteFraction=n 設(shè)置一個比率n, 而refill_waste的值就是(TLAB_SIZE/n), 即TLAB空間較小,, 大對象無法分配在TLAB,,所以會直接分配到堆上,TLAB較小也很容易裝滿, 因此當(dāng)TLAB的空間不夠分配一個新對象, 就會考慮廢棄當(dāng)前TLAB空間還是直接分配到堆上, 就會使用此參數(shù)進(jìn)行判斷, 小于refill_waste就允許廢棄, 而新建TLAB來分配對象,,而大于refill_waste就直接在堆上分配, 默認(rèn)是64
-XX:+ResizeTLAB 開啟TLAB自動調(diào)整大小, 默認(rèn)是開啟的, 若要關(guān)閉把+號換成-號即可
-XX:TLABSize=n 設(shè)置一個TLAB的大小, 前提先關(guān)閉TLAB的自動調(diào)整
4. 性能調(diào)優(yōu)工具
4.1 jps(Java Virtual Machine Process Status Tool)
主要用來輸出JVM中運行的進(jìn)程狀態(tài)信息,。語法格式如下:
jps [options] [hostid]
# hostid語法如下:
[protocol:][[//]hostname][:port][/servername]
protocol - 如果protocol及hostname都沒有指定,那表示的是與當(dāng)前環(huán)境相關(guān)的本地協(xié)議,,如果指定了hostname卻沒有指定protocol,,那么protocol的默認(rèn)就是rmi。
hostname - 服務(wù)器的IP或者名稱,,沒有指定則表示本機(jī),。
port - 遠(yuǎn)程rmi的端口,如果沒有指定則默認(rèn)為1099,。
Servername - 注冊到RMI注冊中心中的jstatd的名稱,。
# 如果不指定hostid就默認(rèn)為當(dāng)前主機(jī)或服務(wù)器。
# 命令行參數(shù)選項
-q 忽略輸出類名,、Jar名和傳入main方法的參數(shù)
-m 輸出傳入main方法的參數(shù)
-l 輸出main類或Jar的全限名
-v 輸出傳入JVM的參數(shù)
-V 輸出通過標(biāo)記的文件傳遞給JVM的參數(shù)(.hotspotrc文件,,或者是通過參數(shù)-XX:Flags=<filename>指定的文件)
-J 用于傳遞jvm選項到由javac調(diào)用的java加載器中,例如,“-J-Xms48m”將把啟動內(nèi)存設(shè)置為48M,,使用-J選項可以非常方便的向基于Java的開發(fā)的底層虛擬機(jī)應(yīng)用程序傳遞參數(shù),。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
4.2 jstack(Java Stack Trace)
主要用來查看某個Java進(jìn)程內(nèi)的線程堆棧信息。語法格式如下:
jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip
# 命令行參數(shù)選項說明如下:
-l 長列表,,會打印出額外的鎖信息,在發(fā)生死鎖時可以用jstack -l pid來觀察鎖持有情況
-m mixed mode,,不僅會輸出Java堆棧信息,,還會輸出C/C++堆棧信息(比如Native方法)
-F 當(dāng)’jstack [-l] pid’沒有相應(yīng)的時候強(qiáng)制打印棧信息
-h | -help打印幫助信息
jstack可以定位到線程堆棧,根據(jù)堆棧信息我們可以定位到具體代碼,,所以它在JVM性能調(diào)優(yōu)中使用得非常多,。
4.3 jmap(Java Memory Map)
jmap用來查看堆內(nèi)存使用狀況,一般結(jié)合jhat使用,。jmap語法格式如下:
如果運行在64位JVM上,,可能需要指定-J-d64命令選項參數(shù)。
jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip
# 參數(shù)說明
executable 產(chǎn)生core dump的java可執(zhí)行程序
core 將被打印信息的core dump文件
remote-hostname-or-ip 遠(yuǎn)程debug服務(wù)的主機(jī)名或ip
server-id 唯一id,假如一臺主機(jī)上多個遠(yuǎn)程debug服務(wù)
pid 需要被打印配相信息的java進(jìn)程id,,可以用jps查問
# 基本參數(shù)
-dump:[live,]format=b,file=<filename> 使用hprof二進(jìn)制形式,輸出jvm的heap內(nèi)容到文件=. live子選項是可選的,,假如指定live選項,那么只輸出活的對象到文件
-finalizerinfo 打印正等候回收的對象的信息
-heap 打印heap的概要信息,GC使用的算法,,heap的配置及wise heap的使用情況
-histo[:live] 打印每個class的實例數(shù)目,內(nèi)存占用,類全名信息. VM的內(nèi)部類名字開頭會加上前綴”*”. 如果live子參數(shù)加上后,只統(tǒng)計活的對象數(shù)量
-permstat 打印classload和jvm heap長久層的信息. 包含每個classloader的名字,活潑性,地址,父classloader和加載的class數(shù)量. 另外,內(nèi)部String的數(shù)量和占用內(nèi)存數(shù)也會打印出來
-F 強(qiáng)迫.在pid沒有相應(yīng)的時候使用-dump或者-histo參數(shù). 在這個模式下,live子參數(shù)無效
-h | -help 打印輔助信息
-J 傳遞參數(shù)給jmap啟動的jvm
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
4.4 jhat(Java Heap Analysis Tool)
Jhat用于對JAVA heap進(jìn)行離線分析的工具,,它可以對不同虛擬機(jī)中導(dǎo)出的heap信息文件進(jìn)行分析
# jmap -dump:format=b,file=dumpFileName pid
jmap -dump:format=b,file=/tmp/dump.dat 21711
jhat -port 9998 /tmp/dump.dat
# 注意如果Dump文件太大,可能需要加上-J-Xmx512m這種參數(shù)指定最大堆內(nèi)存
# 在瀏覽器中輸入主機(jī)地址:9998查看
另外,,可以使用Eclipse插件MAT(Memory Analyzer Tool)對dump文件進(jìn)行分析,。
4.5 jstat(Java Virtual Machine Statistics Monitoring Tool)
Jstat用于監(jiān)控基于HotSpot的JVM,對其堆的使用情況進(jìn)行實時的命令行的統(tǒng)計,,使用jstat我們可以對指定的JVM做如下監(jiān)控:
- 類的加載及卸載情況
- 查看新生代,、老生代及持久代的容量及使用情況
- 查看新生代、老生代及持久代的垃圾收集情況,,包括垃圾回收的次數(shù)及垃圾回收所占用的時間
- 查看新生代中Eden區(qū)及Survior區(qū)中容量及分配情況等
語法:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
generalOption - 單個的常用的命令行選項,,如-help, -options, 或 -version。
outputOptions -一個或多個輸出選項,,由單個的statOption選項組成,,可以和-t, -h, and -J等選項配合使用。
statOption 根據(jù)jstat統(tǒng)計的維度不同,,可以使用如下表中的選項進(jìn)行不同維度的統(tǒng)計,,不同的操作系統(tǒng)支持的選項可能會不一樣,可以通過-options選項,,查看不同操作系統(tǒng)所支持選項
-h n 用于指定每隔幾行就輸出列頭,,如果不指定,默認(rèn)是只在第一行出現(xiàn)列頭。
-J javaOption 用于將給定的javaOption傳給java應(yīng)用程序加載器,,例如,,“-J-Xms48m”將把啟動內(nèi)存設(shè)置為48M
-t n 用于在輸出內(nèi)容的第一列顯示時間戳,這個時間戳代表的時JVM開始啟動到現(xiàn)在的時間
vmid VM的進(jìn)程號,,即當(dāng)前運行的java進(jìn)程號
interval 間隔時間,,單位可以是秒或者毫秒,通過指定s或ms確定,,默認(rèn)單位為毫秒
count 打印次數(shù),,如果缺省則打印無數(shù)次
統(tǒng)計維度與輸出
- class 用于查看類加載情況的統(tǒng)計
列名 |
說明 |
Loaded |
加載了的類的數(shù)量 |
Bytes |
加載了的類的大小,單為Kb |
Unloaded |
卸載了的類的數(shù)量 |
Bytes |
卸載了的類的大小,,單為Kb |
Time |
花在類的加載及卸載的時間 |
2. compiler 用于查看HotSpot中即時編譯器編譯情況的統(tǒng)計
列名 |
說明 |
Compiled |
編譯任務(wù)執(zhí)行的次數(shù) |
Failed |
編譯任務(wù)執(zhí)行失敗的次數(shù) |
Invalid |
編譯任務(wù)非法執(zhí)行的次數(shù) |
Time |
執(zhí)行編譯花費的時間 |
FailedType |
最后一次編譯失敗的編譯類型 |
FailedMethod |
最后一次編譯失敗的類名及方法名 |
3. gc 用于查看JVM中堆的垃圾收集情況的統(tǒng)計
列名 |
說明 |
S0C |
新生代中Survivor space中S0當(dāng)前容量的大?。↘B) |
S1C |
新生代中Survivor space中S1當(dāng)前容量的大小(KB) |
S0U |
新生代中Survivor space中S0容量使用的大?。↘B) |
S1U |
新生代中Survivor space中S1容量使用的大?。↘B) |
EC |
Eden space當(dāng)前容量的大小(KB) |
EU |
Eden space容量使用的大?。↘B) |
OC |
Old space當(dāng)前容量的大?。↘B) |
OU |
Old space使用容量的大小(KB) |
PC |
Permanent space當(dāng)前容量的大?。↘B) |
PU |
Permanent space使用容量的大?。↘B) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
YGCT |
從應(yīng)用程序啟動到采樣時 Young GC 所用的時間(秒) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
FGCT |
從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(秒) |
GCT |
T從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒),它的值等于YGC+FGC |
4. gccapacity 用于查看新生代,、老生代及持久代的存儲容量情況
列名 |
說明 |
NGCMN |
新生代的最小容量大?。↘B) |
NGCMX |
新生代的最大容量大小(KB) |
NGC |
當(dāng)前新生代的容量大?。↘B) |
S0C |
當(dāng)前新生代中survivor space 0的容量大?。↘B) |
S1C |
當(dāng)前新生代中survivor space 1的容量大小(KB) |
EC |
Eden space當(dāng)前容量的大?。↘B) |
OGCMN |
老生代的最小容量大?。↘B) |
OGCMX |
老生代的最大容量大小(KB) |
OGC |
當(dāng)前老生代的容量大?。↘B) |
OC |
當(dāng)前老生代的空間容量大?。↘B) |
PGCMN |
持久代的最小容量大小(KB) |
PGCMX |
持久代的最大容量大?。↘B) |
PGC |
當(dāng)前持久代的容量大?。↘B) |
PC |
當(dāng)前持久代的空間容量大小(KB) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
5. gccause 用于查看垃圾收集的統(tǒng)計情況(這個和-gcutil選項一樣),,如果有發(fā)生垃圾收集,,它還會顯示最后一次及當(dāng)前正在發(fā)生垃圾收集的原因。
列名 |
說明 |
LGCC |
最后一次垃圾收集的原因,可能為“unknown GCCause”,、“System.gc()”等 |
GCC |
當(dāng)前垃圾收集的原因 |
6. gcnew 用于查看新生代垃圾收集的情況
列名 |
說明 |
S0C |
當(dāng)前新生代中survivor space 0的容量大?。↘B) |
S1C |
當(dāng)前新生代中survivor space 1的容量大小(KB) |
S0U |
S0已經(jīng)使用的大?。↘B) |
S1U |
S1已經(jīng)使用的大?。↘B) |
TT |
Tenuring threshold,要了解這個參數(shù),,我們需要了解一點Java內(nèi)存對象的結(jié)構(gòu),,在Sun JVM中,(除了數(shù)組之外的)對象都有兩個機(jī)器字(words)的頭部,。第一個字中包含這個對象的標(biāo)示哈希碼以及其他一些類似鎖狀態(tài)和等標(biāo)識信息,,第二個字中包含一個指向?qū)ο蟮念惖囊?,其中第二個字節(jié)就會被垃圾收集算法使用到,。
在新生代中做垃圾收集的時候,每次復(fù)制一個對象后,,將增加這個對象的收集計數(shù),,當(dāng)一個對象在新生代中被復(fù)制了一定次數(shù)后,該算法即判定該對象是長周期的對象,,把他移動到老生代,,這個閾值叫著tenuring threshold。這個閾值用于表示某個/些在執(zhí)行批定次數(shù)youngGC后還活著的對象,,即使此時新生的的Survior沒有滿,,也同樣被認(rèn)為是長周期對象,將會被移到老生代中,。 |
MTT |
Maximum tenuring threshold,,用于表示TT的最大值。 |
DSS |
Desired survivor size (KB).可以參與這里:http://blog.csdn.net/yangjun2/article/details/6542357 |
EC |
Eden space當(dāng)前容量的大?。↘B) |
EU |
Eden space已經(jīng)使用的大?。↘B) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
YGCT |
從應(yīng)用程序啟動到采樣時 Young GC 所用的時間(單位秒) |
7. gcnewcapacity 用于查看新生代的存儲容量情況
列名 |
說明 |
NGCMN |
新生代的最小容量大小(KB) |
NGCMX |
新生代的最大容量大?。↘B) |
NGC |
當(dāng)前新生代的容量大?。↘B) |
S0CMX |
新生代中SO的最大容量大小(KB) |
S0C |
當(dāng)前新生代中SO的容量大?。↘B) |
S1CMX |
新生代中S1的最大容量大?。↘B) |
S1C |
當(dāng)前新生代中S1的容量大小(KB) |
ECMX |
新生代中Eden的最大容量大?。↘B) |
EC |
當(dāng)前新生代中Eden的容量大?。↘B) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
8. gcold 用于查看老生代及持久代發(fā)生GC的情況
列名 |
說明 |
PC |
當(dāng)前持久代容量的大小(KB) |
PU |
持久代使用容量的大小(KB) |
OC |
當(dāng)前老年代容量的大?。↘B) |
OU |
老年代使用容量的大?。↘B) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
FGCT |
從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(單位秒) |
GCT |
從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒),它的值等于YGC+FGC |
9. gcoldcapacity 用于查看老生代的容量
列名 |
說明 |
OGCMN |
老生代的最小容量大?。↘B) |
OGCMX |
老生代的最大容量大?。↘B) |
OGC |
當(dāng)前老生代的容量大小(KB) |
OC |
當(dāng)前新生代的空間容量大?。↘B) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
FGCT |
從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(單位秒) |
GCT |
從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒),,它的值等于YGC+FGC |
10. gcpermcapacity 用于查看持久代的容量
列名 |
說明 |
PGCMN |
持久代的最小容量大小(KB) |
PGCMX |
持久代的最大容量大?。↘B) |
PGC |
當(dāng)前持久代的容量大?。↘B) |
PC |
當(dāng)前持久代的空間容量大小(KB) |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
FGC |
Full GC次數(shù) |
FGCT |
從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(單位秒) |
GCT |
從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒),,它的值等于YGC+FGC |
11. gcutil 用于查看新生代,、老生代及持代垃圾收集的情況
列名 |
說明 |
S0 |
Heap上的 Survivor space 0 區(qū)已使用空間的百分比 |
S1 |
Heap上的 Survivor space 1 區(qū)已使用空間的百分比 |
E |
Heap上的 Eden space 區(qū)已使用空間的百分比 |
O |
Heap上的 Old space 區(qū)已使用空間的百分比 |
P |
Perm space 區(qū)已使用空間的百分比 |
YGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Young GC 的次數(shù) |
YGCT |
從應(yīng)用程序啟動到采樣時 Young GC 所用的時間(單位秒) |
FGC |
從應(yīng)用程序啟動到采樣時發(fā)生 Full GC 的次數(shù) |
FGCT |
從應(yīng)用程序啟動到采樣時 Full GC 所用的時間(單位秒) |
GCT |
從應(yīng)用程序啟動到采樣時用于垃圾回收的總時間(單位秒),它的值等于YGC+FGC |
12. printcompilation HotSpot編譯方法的統(tǒng)計
列名 |
說明 |
Compiled |
編譯任務(wù)執(zhí)行的次數(shù) |
Size |
方法的字節(jié)碼所占的字節(jié)數(shù) |
Type |
編譯類型 |
Method |
指定確定被編譯方法的類名及方法名,,類名中使名“/”而不是“.”做為命名分隔符,,方法名是被指定的類中的方法,這兩個字段的格式是由HotSpot中的“-XX:+PrintComplation”選項確定的,。 |
示例
jstat -gc 1618 250 4
4.6 jvisualvm(Java Virtual Machine Monitoring, Troubleshooting, and Profiling Tool)
jvisualvm同jconsole都是一個基于圖形化界面的,、可以查看本地及遠(yuǎn)程的JAVA GUI監(jiān)控工具,Jvisualvm同jconsole的使用方式一樣,,直接在命令行打入Jvisualvm即可啟動,,不過Jvisualvm相比,界面更美觀一些,,數(shù)據(jù)更實時,。
4.7 jconsole
一個java GUI監(jiān)視工具,可以以圖表化的形式顯示各種數(shù)據(jù),。并可通過遠(yuǎn)程連接監(jiān)視遠(yuǎn)程的服務(wù)器VM,。用java寫的GUI程序,用來監(jiān)控VM,,并可監(jiān)控遠(yuǎn)程的VM,,非常易用,而且功能非常強(qiáng),。命令行里打 jconsole,,選則進(jìn)程就可以了。
需要注意的就是在運行jconsole之前,,必須要先設(shè)置環(huán)境變量DISPLAY,,否則會報錯誤,,Linux下設(shè)置環(huán)境變量如下:
export DISPLAY=:0.0
4.8 jprofile
JProfiler是一個需要商業(yè)授權(quán)的全功能的Java剖析工具(profiler),專用于分析J2SE和J2EE應(yīng)用程序,。
它把CPU,、執(zhí)行緒和內(nèi)存的剖析組合在一個強(qiáng)大的應(yīng)用中。JProfiler可提供許多IDE整合和應(yīng)用服務(wù)器整合用途,。JProfiler直覺式的GUI讓你可以找到效能瓶頸,、抓出內(nèi)存漏失(memory leaks)、并解決執(zhí)行緒的問題,。它讓你得以對heap walker作資源回收器的root analysis,,可以輕易找出內(nèi)存漏失;heap快照(snapshot)模式讓未被參照(reference)的對象,、稍微被參照的對象,、或在終結(jié)(finalization)隊列的對象都會被移除;整合精靈以便剖析瀏覽器的Java外掛功能,。
4.9 jca
Java線程分析工具,,專業(yè)的線程分析工具兼容sun/oracle JDK dump線程堆,圖形化顯示線程概括信息,,非常容易的定位問題,。
jca是一個類工具 啟動方法:
java -jar jca433.jar
4.10 jinfo命令(Java Configuration Info)
jinfo可以輸出并修改運行時的java 進(jìn)程的opts,。用處比較簡單,,用于輸出JAVA系統(tǒng)參數(shù)及命令行參數(shù)。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788,。
4.11 Jdb命令(The Java Debugger)
用來對core文件和正在運行的Java進(jìn)程進(jìn)行實時地調(diào)試,,里面包含了豐富的命令幫助您進(jìn)行調(diào)試。
4.12 Jstatd命令(Java Statistics Monitoring Daemon)
jstatd是一個基于RMI(Remove Method Invocation)的服務(wù)程序,,它用于監(jiān)控基于HotSpot的JVM中資源的創(chuàng)建及銷毀,,并且提供了一個遠(yuǎn)程接口允許遠(yuǎn)程的監(jiān)控工具連接到本地的JVM執(zhí)行命令。
jstatd是基于RMI的,,所以在運行jstatd的服務(wù)器上必須存在RMI注冊中心,,如果沒有通過選項”-p port”指定要連接的端口,jstatd會嘗試連接RMI注冊中心的默認(rèn)端口,。后面會談到如何連接到一個默認(rèn)的RMI內(nèi)部注冊中心,,如何禁止默認(rèn)的RMI內(nèi)部注冊中心的創(chuàng)建,以及如何啟動一個外部注冊中心,。
參數(shù)選項
-nr 如果RMI注冊中心沒有找到,,不會創(chuàng)建一個內(nèi)部的RMI注冊中心。
-p port RMI注冊中心的端口號,,默認(rèn)為1099,。
-n rminame 默認(rèn)為JStatRemoteHost,;如果同一臺主機(jī)上同時運行了多個jstatd服務(wù),rminame可以用于唯一確定一個jstatd服務(wù),;這里需要注意一下,,如果開啟了這個選項,那么監(jiān)控客戶端遠(yuǎn)程連接時,,必須同時指定hostid及vmid,,才可以唯一確定要連接的服務(wù),這個可以參看jps章節(jié)中列出遠(yuǎn)程服務(wù)器上Java進(jìn)程的示例,。
-J 用于傳遞jvm選項到由javac調(diào)用的java加載器中,,例如,“-J-Xms48m”將把啟動內(nèi)存設(shè)置為48M,,使用-J選項可以非常方便的向基于Java的開發(fā)的底層虛擬機(jī)應(yīng)用程序傳遞參數(shù),。
安全性
jstatd服務(wù)只能監(jiān)視具有適當(dāng)?shù)谋镜卦L問權(quán)限的JVM,因此jstatd進(jìn)程與被監(jiān)控的JVM必須運行在相同的用戶權(quán)限中,。但是有一些特殊的用戶權(quán)限,,如基于UNIX(TM)為系統(tǒng)的root用戶,它有權(quán)限訪問系統(tǒng)中所有JVM的資源,,如果jstatd進(jìn)程運行在這種權(quán)限中,,那么它可以監(jiān)視系統(tǒng)中的所有JVM,但是這也帶來了額外的安全問題,。
示例
# 使用內(nèi)部RMI注冊中心(默認(rèn)端口是1099),,啟動jstatd
jstatd -J-Djava.security.policy=jstatd.all.policy
# 使用外部的RMI注冊中心,啟動jstatd
rmiregistry&jstatd -J-Djava.security.policy=all.policy
# 外部的RMI注冊中心來啟動jstatd,,此注冊中心的端口為2020
rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020
# 外部的RMI注冊中心來啟動jstatd,,此注冊中心的端口為2020,并且綁定到RMI注冊中心的名為AlternateJstatdServerName
rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName
# 禁止內(nèi)部RMI注冊中心的創(chuàng)建
jstatd -J-Djava.security.policy=all.policy -nr
# 開啟RMI日記記錄,,jstatd運行在開啟了日志記錄功能的RMI注冊中
jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
4.13 httpwatch
網(wǎng)頁數(shù)據(jù)分析工具,,對客戶端到服務(wù)器端的請求,響應(yīng)數(shù)據(jù)有效的監(jiān)控分析,。
5. 生產(chǎn)環(huán)境示例
5.1 Tomcat7
catalina.sh(只運行一個Tomcat)
# 8G內(nèi)存
JAVA_OPTS="
-Dfile.encoding=UTF-8
-server
-Djava.awt.headless=true
-Xms6144m
-Xmx6144m
-XX:NewSize=1024m
-XX:MaxNewSize=2048m
-XX:PermSize=512m
-XX:MaxPermSize=512m
-XX:MaxTenuringThreshold=15
-XX:NewRatio=2
-XX:+AggressiveOpts
-XX:+UseBiasedLocking
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:LargePageSizeInBytes=128m
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+DisableExplicitGC"
# 16G內(nèi)存(垃圾回收略)
JAVA_OPTS="
-Dfile.encoding=UTF-8
-server
-Xms13312m
-Xmx13312m
-XX:NewSize=3072m
-XX:MaxNewSize=4096m
-XX:PermSize=512m
-XX:MaxPermSize=512m
-XX:MaxTenuringThreshold=10
-XX:NewRatio=2
-XX:+DisableExplicitGC"
# 32G內(nèi)存(垃圾回收略)
JAVA_OPTS="
-Dfile.encoding=UTF-8
-server
-Xms29696m
-Xmx29696m
-XX:NewSize=6144m
-XX:MaxNewSize=9216m
-XX:PermSize=1024m
-XX:MaxPermSize=1024m
-XX:MaxTenuringThreshold=10
-XX:NewRatio=2
-XX:+DisableExplicitGC"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
5.2 Hadoop
建議Hadoop進(jìn)程的GC參數(shù)加上如下選項,,很多商業(yè)版都默認(rèn)加上了,這對JDK性能提升有很大幫助:
-XX:CMSInitiatingOccupancyFraction=70
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseConcMarkSweepGC
-XX:-CMSConcurrentMTEnabled
-XX:+CMSIncrementalMode
-Djava.net.preferIPv4Stack=true
|