原文地址:http://blog.csdn.net/u013980127/article/details/53913994
1. JVM堆內存劃分
這兩天看到下面這篇文章的圖不錯。
1.1 JDK7及以前的版本
其中最上一層是Nursery內存,一個對象被創建以後首先被放到Nursery中的Eden內
存中,如果存活期超兩個Survivor之後就會被轉移到長時內存中(Old Generation)中。
永久內存中存放着對象的方法、變量等元數據信息。通過如果永久內存不夠,就會得到如下錯誤:
- 1
1.2 JDK8版本
JDK8中把存放元數據中的永久內存從堆內存中移到了本地內存(native memory)中,這樣永久內存就不再佔用堆內存,它可以通過自動增長來避免JDK7以及前期版本中常見的永久內存錯誤(java.lang.OutOfMemoryError: PermGen)。
JDK8也提供了一個新的設置Matespace內存大小的參數:
- 1
注意:如果不設置JVM將會根據一定的策略自動增加本地元內存空間。如果你設置的元內存空間過小,你的應用程序可能得到以下錯誤:
- 1
2. JVM參數
-XX 參數被稱爲不穩定參數,此類參數的設置很容易引起JVM性能上的差異。
不穩定參數語法規則:
布爾類型
- 1
- 2
數字類型
- 1
- 2
- 3
- 4
- 5
字符串類型
- 1
- 2
- 3
- 4
- 5
2.1 行爲選項
選項 | 默認值 | 描述 |
---|---|---|
-XX:-AllowUserSignalHandlers | 限於Linux和Solaris默認關閉 | 允許爲java進程安裝信號處理器。 |
-XX:AltStackSize=16384 | 僅適用於Solaris,從5.0中刪除 | 備用信號堆棧大小(以字節爲單位) |
-XX:-DisableExplicitGC | 默認關閉 | 禁止在運行期顯式地調用 System.gc()。 注意:你熟悉的代碼裏沒調用System.gc(),不代表你依賴的框架工具沒在使用。 |
-XX:+FailOverToOldVerifier | Java6新引入選項,默認啓用 | 如果新的Class校驗器檢查失敗,則使用老的校驗器。解決兼容性問題。 關聯選項:-XX:+UseSplitVerifier |
-XX:+HandlePromotionFailure | Java1.5以前默認關閉 Java1.6後默認啓用 | 新生代收集擔保,於年老代預留內存。 |
-XX:+MaxFDLimit | 限於Solaris 默認啓用 | 設置java進程可用文件描述符爲操作系統允許的最大值。 |
-XX:PreBlockSpin | 默認10 | 控制多線程自旋鎖優化的自旋次數 前置選項: -XX:+UseSpinning |
-XX:-RelaxAccessControlCheck | 默認關閉 Java1.6引入 | 在Class校驗器中,放鬆對訪問控制的檢查。 作用與reflection裏的setAccessible類似。 |
-XX:+ScavengeBeforeFullGC | 默認啓用 | 在Full GC前觸發一次Minor GC |
-XX:+UseAltSigs | 限於Solaris 默認啓用 | 爲了防止與其他發送信號的應用程序衝突,允許使用候補信號替代 SIGUSR1和SIGUSR2。 |
-XX:+UseBoundThreads | 限於Solaris 默認啓用 | 綁定所有的用戶線程到內核線程。 減少線程進入飢餓狀態(得不到任何cpu time)的次數。 |
-XX:-UseConcMarkSweepGC | 默認關閉 Java1.4引入 | 啓用CMS低停頓垃圾收集器。 |
-XX:+UseGCOverheadLimit | 默認啓用 Java1.6引入 | 限制GC的運行時間。如果GC耗時過長,就拋OutOfMemoryError。 |
-XX:+UseLWPSynchronization | 限於solaris, 默認啓用, Java1.4引入 | 使用輕量級進程(內核線程)替換線程同步。 |
-XX:-UseParallelGC | -server時啓用, 其他情況下:默認關閉, Java1.4引入 | 爲新生代使用並行清除,年老代使用單線程Mark-Sweep-Compact的垃圾收集器。 |
-XX:-UseParallelOldGC | 默認關閉, Java1.5引入 | 爲老年代和新生代都使用並行清除的垃圾收集器。開啓此選項將自動開啓-XX:+UseParallelGC 選項 |
-XX:-UseSerialGC | -client時啓用, 默認關閉, Java1.5引入 | 使用串行垃圾收集器。 |
-XX:-UseSpinning | Java1.4.2和1.5需要手動啓用, Java1.6默認已啓用 | 啓用多線程自旋鎖優化。 關聯選項: -XX:PreBlockSpin=10 |
-XX:+UseTLAB | Java1.4.2以前和使用-client選項時:默認關閉, 其餘版本默認啓用 | 啓用線程本地緩存區(Thread Local) |
-XX:+UseSplitVerifier | Java1.5默認關閉, Java1.6默認啓用 | 使用新的Class類型校驗器 。 關聯選項: -XX:+FailOverToOldVerifier |
-XX:+UseThreadPriorities | 默認啓用 | 使用本地線程的優先級。 |
-XX:+UseVMInterruptibleIO | 限於solaris, 默認啓用, Java1.6引入 | 在solaris中,允許運行時中斷線程。 |
2.2 性能選項
選項 | 默認值 | 描述 |
---|---|---|
-XX:+AggressiveOpts | Java1.5 引入 默認關閉 Java1.6後默認開啓 | 開啓編譯器性能優化。 |
-XX:CompileThreshold=10000 | 默認值:1000 | 通過JIT編譯器,將方法編譯成機器碼的觸發閥值,可以理解爲調用方法的次數,例如調1000次,將方法編譯爲機器碼。 [-client: 1,500] |
-XX:LargePageSizeInBytes=4m | 默認值:4m amd64位:2m | 設置堆內存的內存最大值。 |
-XX:MaxHeapFreeRatio=70 | 默認70 | GC後,如果發現空閒堆內存佔到整個預估上限值的70%,則收縮預估上限值。 |
-XX:MaxNewSize=size | 1.3.1 Sparc: 32m 1.3.1 x86: 2.5m | 新生代佔整個堆內存的最大值。從Java1.4開始, MaxNewSize成爲 NewRatio的一個函數 |
-XX:MaxPermSize=64m | Java1.5以後::64 bit VMs會增大預設值的30% 1.4 amd64::96m 1.3.1 -client: 32m 其他默認 64m | Perm(俗稱方法區)佔整個堆內存的最大值。 |
-XX:MinHeapFreeRatio=40 | 默認值:40 | GC後,如果發現空閒堆內存佔到整個預估上限值的40%,則增大上限值。 關聯選項: -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 | 新生代和年老代的堆內存佔用比例。 例如2表示新生代佔年老代的1/2,佔整個堆內存的1/3。 |
-XX:NewSize=2m | 5.0以後: 64 bit Vms 會增大預設值的30% x86: 1m x86, 5.0以後: 640k 其他:2.125m | 新生代預估上限的默認值。 |
-XX:ReservedCodeCacheSize=32m | Solaris 64-bit, amd64, -server x86: 48m 1.5.0_06之前, Solaris 64-bit amd64: 1024m 其他:32m | 設置代碼緩存的最大值,編譯時用。 |
-XX:SurvivorRatio=8 | Solaris amd64: 6 Sparc in 1.3.1: 25 Solaris platforms 5.0以前: 32 其他:8 | Eden與Survivor的佔用比例。例如8表示,一個survivor區佔用 1/8 的Eden內存,即1/10的新生代內存,爲什麼不是1/9? 因爲我們的新生代有2個survivor,即S1和S22。所以survivor總共是佔用新生代內存的 2/10,Eden與新生代的佔比則爲 8/10。 |
-XX:TargetSurvivorRatio=50 | 默認值:50 | 實際使用的survivor空間大小佔比。默認是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後引入 默認關閉。 Java1.6默認啓用。 | 啓用偏向鎖 |
-XX:+UseFastAccessorMethods | 默認啓用 | 優化原始類型的getter方法性能。 |
-XX:-UseISM | 默認啓用 | 啓用solaris的ISM |
-XX:+UseLargePages | Java1.5 update 5後引入 默認關閉 Java1.6默認啓用 | 啓用大內存分頁。 關聯選項: -XX:LargePageSizeInBytes=4m |
-XX:+UseMPSS | Java1.4.1 之前默認關閉 其他版本默認啓用 | 啓用solaris的MPSS,不能與ISM同時使用。 |
-XX:+UseStringCache | 默認開啓 | 緩存常用字符串。 |
-XX:AllocatePrefetchLines=1 | 默認值:1 | 在使用JIT生成的預讀取指令分配對象後讀取的緩存行數。如果上次分配的對象是一個實例則默認值是1,如果是一個數組則是3 |
-XX:AllocatePrefetchStyle=1 | 默認值:1 | 預讀取指令的生成代碼風格 0- 無預讀取指令生成 1-在每次分配後執行預讀取命令 2-當預讀取指令執行後使用TLAB()分配水印指針來找回入口 |
-XX:+UseCompressedStrings | Java1.6 update 21引入 | 其中,對於不需要16位字符的字符串,可以使用byte[] 而非char[]。對於許多應用,這可以節省內存,但速度較慢(5%-10%) |
-XX:+OptimizeStringConcat | Java1.6 update 20引入 | 在可能的情況下優化字符串連接操作。 |
2.3 調試選項
選項 | 默認值 | 描述 |
---|---|---|
-XX:-CITime | 默認啓用 | 打印JIT編譯器編譯耗時。 |
-XX:ErrorFile=./hs_err_pid.log | Java1.6引入 | 如果JVM crashed,將錯誤日誌輸出到指定文件路徑。 |
-XX:-ExtendedDTraceProbes | Java6引入,限於solaris 默認關閉 | 啓用dtrace診斷 |
-XX:HeapDumpPath=./java_pid.hprof | 默認是java進程啓動位置 | 堆內存快照的存儲文件路徑。 |
-XX:-HeapDumpOnOutOfMemoryError | 默認關閉 | 在java.lang.OutOfMemoryError 異常出現時,輸出一個dump.core文件,記錄當時的堆內存快照(見 -XX:HeapDumpPath 的描述) |
-XX:OnError=”\;\” | Java1.4引入 | 當java每拋出一個ERROR時,運行指定命令行指令集。指令集是與OS環境相關的,在Linux下多數是.sh腳本,windows下是.bat批處理。 |
-XX:OnOutOfMemoryError=”\;\” | Java1.4.2 update 12和Java6時引入 | 當第一次發生java.lang.OutOfMemoryError 時,運行指定命令行指令集。指令集是與OS環境相關的,在linux下多數是.sh腳本,windows下是.bat批處理。 |
-XX:-PrintClassHistogram | 默認關閉 | 在Windows下, 按ctrl-break或Linux下是執行kill -3(發送SIGQUIT信號)時,打印class柱狀圖。 jmap -histo pid也實現了相同的功能。 |
-XX:-PrintConcurrentLocks | 默認關閉 | 在thread dump的同時,打印java.util.concurrent的鎖狀態。 jstack -l pid 也同樣實現了同樣的功能。 |
-XX:-PrintCommandLineFlags | Java1.5 引入,默認關閉 | Java啓動時,往stdout打印當前啓用的非穩態jvm options。 例如: -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+DoEscapeAnalysis |
-XX:-PrintCompilation | 默認關閉 | 往stdout打印方法被JIT編譯時的信息。 |
-XX:-PrintGC | 默認關閉 | 開啓GC日誌打印。 顯示結果例如: [Full GC 131115K->7482K(1015808K), 0.1633180 secs] 該選項可通過 com.sun.management.HotSpotDiagnosticMXBean API 和 jconsole 動態啓用。 |
-XX:-PrintGCDetails | Java1.4引入,默認關閉 | 打印GC回收的詳細信息。 顯示結果例如: [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 動態啓用。 |
-XX:-PrintGCTimeStamps | 默認關閉 | 打印GC停頓耗時。 顯示結果例如: 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 動態啓用。 |
-XX:-PrintTenuringDistribution | 默認關閉 | 打印對象的存活期限信息。 顯示結果例如: [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 | 默認關閉 | 打印class裝載信息到stdout。記Loaded狀態。 例如: [Loaded java.lang.Object from /opt/taobao/install/jdk1.6.0_07/jre/lib/rt.jar] |
-XX:-TraceClassLoadingPreorder | 1.4.2引入,默認關閉 | 按class的引用/依賴順序打印類裝載信息到stdout。不同於 TraceClassLoading,本選項只記 Loading狀態。 例如: [Loading java.lang.Object from /home/confsrv/jdk1.6.0_14/jre/lib/rt.jar] |
-XX:-TraceClassResolution | 1.4.2引入,默認關閉 | 打印所有靜態類,常量的代碼引用位置。用於debug。 例如: RESOLVE java.util.HashMap java.util.HashMap |
-XX:-TraceClassUnloading | 默認關閉 | 打印class的卸載信息到stdout。記Unloaded狀態。 |
-XX:-TraceLoaderConstraints | Java1.6 引入,默認關閉 | 打印class的裝載策略變化信息到stdout。 裝載策略變化是實現classloader隔離/名稱空間一致性的關鍵技術。 |
-XX:+PerfSaveDataToFile | 默認啓用 | 當java進程因java.lang.OutOfMemoryError 異常或crashed 被強制終止後,生成一個堆快照文件。 |
-XX:ParallelGCThreads=n | 默認值:隨JVM運行平臺不同而異 | 配置並行收集器的線程數,即:同時多少個線程一起進行垃圾回收。此值最好配置與處理器數目相等。 |
-XX:+UseCompressedOops | 32位默認關閉,64位默認啓動 | 使用compressed pointers。這個參數默認在64bit的環境下默認啓動,但是如果JVM的內存達到32G後,這個參數就會默認爲不啓動,因爲32G內存後,壓縮就沒有多大必要了,要管理那麼大的內存指針也需要很大的寬度了 |
-XX:+AlwaysPreTouch | 默認關閉 | 在JVM 初始化時預先對Java堆進行摸底。 |
-XX:AllocatePrefetchDistance=n | 默認值取決於當前JVM 設置 | 爲對象分配設置預取距離。 |
-XX:InlineSmallCode=n | 默認值取決於當前JVM 設置 | 當編譯的代碼小於指定的值時,內聯編譯的代碼。 |
-XX:MaxInlineSize=35 | 默認值:35 | 內聯方法的最大字節數。 |
-XX:FreqInlineSize=n | 默認值取決於當前JVM 設置 | 內聯頻繁執行的方法的最大字節碼大小。 |
-XX:LoopUnrollLimit=n | 默認值取決於當前JVM 設置 | 代表節點數目小於給定值時打開循環體。 |
-XX:InitialTenuringThreshold=7 | 默認值:7 | 設置初始的對象在新生代中最大存活次數。 |
-XX:MaxTenuringThreshold=n | 默認值:15,最大值:15 | 設置對象在新生代中最大的存活次數,最大值15,並行回收機制默認爲15,CMS默認爲4。 |
-Xloggc: | 默認關閉 | 輸出GC 詳細日誌信息至指定文件。 |
-XX:-UseGCLogFileRotation | 默認關閉 | 開啓GC 日誌文件切分功能,前置選項 -Xloggc |
-XX:NumberOfGClogFiles=1 | 必須>=1,默認值:1 | 設置切分GC 日誌文件數量,文件命名格式:.0, .1, …, .n-1 |
-XX:GCLogFileSize=8K | 必須>=8K,默認值:8K | GC日誌文件切分大小。 |
3. 垃圾收集器
3.1 串行回收器
3.1.1 新生代串行回收器
特點
- 它僅僅使用單線程進行垃圾回收
- 它是獨佔式的垃圾回收
- 進行垃圾回收時, Java應用程序中的線程都需要暫停(Stop-The-World)
- 使用複製算法
- 適合CPU等硬件不是很好的場合
設置參數
- 1
3.1.2 老年代串行回收器
特點
- 同新生代串行回收器一樣, 單線程, 獨佔式的垃圾回收器
- 通常老年代垃圾回收比新生代回收要更長時間, 所以可能會使應用程序停頓較長時間
設置參數
- 1
- 2
- 3
3.2 並行回收器
3.2.1 新生代ParNew回收器
特點
- 將串行回收多線程化
- 使用複製算法
- 垃圾回收時, 應用程序仍會暫停, 只不過由於是多線程回收, 在多核CPU上,回收效率會高於串行回收器, 反之在單核CPU, 效率會不如串行回收器
設置參數
- 1
- 2
- 3
3.2.2 新生代ParallelGC回收器
特點
- 同ParNew回收器一樣, 不同的地方在於,它非常關注系統的吞吐量(通過參數控制)
- 使用複製算法
- 支持自適應的GC調節策略
設置參數
- 1
- 2
- 3
- 4
- 5
3.2.3 老年代ParallelOldGC回收器
特點
- 同新生代的ParallelGC回收器一樣, 是屬於老年代的關注吞吐量的多線程併發回收器
- 使用標記壓縮算法
設置參數
- 1
- 2
3.3 CMS回收器(Concurrent Mark Sweep,併發標記清除)
3.3.1 老年代的併發回收器
特點
- 是併發回收, 非獨佔式的回收器, 大部分時候應用程序不會停止運行
- 針對年老代的回收器
- 使用併發標記清除算法, 因此回收後會有內存碎片, 可以使參數設置進行內存碎片的壓縮整理
- 與ParallelGC和ParallelOldGC不同, CMS主要關注系統停頓時間
主要步驟
- 初始標記
- 併發標記
- 預清理
- 重新標記
- 併發清理
- 併發重置
注:初始標記與重新標記是獨佔系統資源的,不能與用戶線程一起執行,而其它階段則可以與用戶線程一起執行
設置參數
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
3.3.2 Class的回收(永久區的回收)
設置參數
- 1
- 2
3.4 G1回收器(jdk1.7後全新的回收器, 用於取代CMS)
3.4.1 概述
特點
- 獨特的垃圾回收策略, 屬於分代垃圾回收器
- 使用分區算法, 不要求eden, 年輕代或老年代的空間都連續
- 並行性: 回收期間, 可由多個線程同時工作, 有效利用多核cpu資源
- 併發性: 與應用程序可交替執行, 部分工作可以和應用程序同時執行
- 分代GC: 分代收集器, 同時兼顧年輕代和老年代
- 空間整理: 回收過程中, 會進行適當對象移動, 減少空間碎片
- 可預見性: G1可選取部分區域進行回收, 可以縮小回收範圍, 減少全局停頓
主要步驟
- 新生代GC
併發標記週期
初始標記新生代GC(此時是並行, 應用程序會暫停止)–>根區域掃描–>併發標記–>重新標記(此時是並行, 應用程序會暫停止)–>獨佔清理(此時應用程序會暫停止)–>併發清理
混合回收
這個階段即會執行正常的年輕代gc, 也會選取一些被標記的老年代區域進行回收, 同時處理新生代和年老輕
若需要, 會進行FullGC
混合GC時發生空間不足
在新生代GC時, survivor區和老年代無法容納倖存對象時
以上兩者都會導致一次FullGC產生
設置參數
- 1
- 2
- 3
- 4
3.4.2 參數選項
選項 | 默認值 | 描述 |
---|---|---|
-XX:+UseG1GC | 默認關閉 | 使用G1垃圾處理器 |
-XX:MaxGCPauseMillis=n | 默認值:4294967295 | 設置並行收集最大暫停時間,這是一個理想目標,JVM將盡最大努力來實現它。 |
-XX:InitiatingHeapOccupancyPercent=n | 默認值:45 | 啓動一個併發垃圾收集週期所需要達到的整堆佔用比例。這個比例是指整個堆的佔用比例而不是某一個代(例如G1),如果這個值是0則代表‘持續做GC’。默認值是45 |
-XX:NewRatio=n | 默認值:2 | 設置年輕代和年老代的比值。例如:值爲3,則表示年輕代與年老代比值爲1:3,年輕代佔整個年輕代年老代和的1/4。 |
-XX:SurvivorRatio=n | 默認值:8 | 年輕代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個年輕代的1/5 |
-XX:MaxTenuringThreshold=n | 默認值:15 | 設置垃圾最大存活閥值。如果設置爲0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設置爲一個較大值,則年輕代對象會在Survivor區進行多次複製,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。 |
-XX:ParallelGCThreads=n | 默認值:隨JVM運行平臺不同而異 | 配置並行收集器的線程數,即:同時多少個線程一起進行垃圾回收。此值最好配置與處理器數目相等。 |
-XX:ConcGCThreads=n | 默認值:隨JVM運行平臺不同而異 | 並行垃圾收集時,使用的線程數。默認值和JVM運行的平臺有關。 |
-XX:G1ReservePercent=n | 默認值:10 | 設置保留用來做假天花板以減少晉升(新生代對象晉升到老生代)失敗可能性的堆數目。 |
-XX:G1HeapRegionSize=n | 默認值根據堆大小而定 | 使用G1垃圾回收器,java堆被劃分成統一大小的區塊。這個選項設置每個區塊的大小。最小值是1Mb,最大值是32Mb。 |
3.4.3 其他GC相關的設置
System.gc()
- 1
- 2
- 3
- 4
- 5
並行GC前額外觸發的新生代GC
- 1
- 2
- 3
對象何時進入老年代
- 1
- 2
- 3
- 4
- 5
- 6
在TLAB上分配對象(Thread Local Allocation Buffer, 線程本地分配緩存)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4. 性能調優工具
4.1 jps(Java Virtual Machine Process Status Tool)
主要用來輸出JVM中運行的進程狀態信息。語法格式如下:
- 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進程內的線程堆棧信息。語法格式如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
jstack可以定位到線程堆棧,根據堆棧信息我們可以定位到具體代碼,所以它在JVM性能調優中使用得非常多。
4.3 jmap(Java Memory Map)
jmap用來查看堆內存使用狀況,一般結合jhat使用。jmap語法格式如下:
如果運行在64位JVM上,可能需要指定-J-d64命令選項參數。
- 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進行離線分析的工具,它可以對不同虛擬機中導出的heap信息文件進行分析
- 1
- 2
- 3
- 4
- 5
- 6
- 7
另外,可以使用Eclipse插件MAT(Memory Analyzer Tool)對dump文件進行分析。
4.5 jstat(Java Virtual Machine Statistics Monitoring Tool)
Jstat用於監控基於HotSpot的JVM,對其堆的使用情況進行實時的命令行的統計,使用jstat我們可以對指定的JVM做如下監控:
- 類的加載及卸載情況
- 查看新生代、老生代及持久代的容量及使用情況
- 查看新生代、老生代及持久代的垃圾收集情況,包括垃圾回收的次數及垃圾回收所佔用的時間
- 查看新生代中Eden區及Survior區中容量及分配情況等
語法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
統計維度與輸出
- class 用於查看類加載情況的統計
列名 | 說明 |
---|---|
Loaded | 加載了的類的數量 |
Bytes | 加載了的類的大小,單爲Kb |
Unloaded | 卸載了的類的數量 |
Bytes | 卸載了的類的大小,單爲Kb |
Time | 花在類的加載及卸載的時間 |
2. compiler 用於查看HotSpot中即時編譯器編譯情況的統計
列名 | 說明 |
---|---|
Compiled | 編譯任務執行的次數 |
Failed | 編譯任務執行失敗的次數 |
Invalid | 編譯任務非法執行的次數 |
Time | 執行編譯花費的時間 |
FailedType | 最後一次編譯失敗的編譯類型 |
FailedMethod | 最後一次編譯失敗的類名及方法名 |
3. gc 用於查看JVM中堆的垃圾收集情況的統計
列名 | 說明 |
---|---|
S0C | 新生代中Survivor space中S0當前容量的大小(KB) |
S1C | 新生代中Survivor space中S1當前容量的大小(KB) |
S0U | 新生代中Survivor space中S0容量使用的大小(KB) |
S1U | 新生代中Survivor space中S1容量使用的大小(KB) |
EC | Eden space當前容量的大小(KB) |
EU | Eden space容量使用的大小(KB) |
OC | Old space當前容量的大小(KB) |
OU | Old space使用容量的大小(KB) |
PC | Permanent space當前容量的大小(KB) |
PU | Permanent space使用容量的大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
YGCT | 從應用程序啓動到採樣時 Young GC 所用的時間(秒) |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
FGCT | 從應用程序啓動到採樣時 Full GC 所用的時間(秒) |
GCT | T從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC |
4. gccapacity 用於查看新生代、老生代及持久代的存儲容量情況
列名 | 說明 |
---|---|
NGCMN | 新生代的最小容量大小(KB) |
NGCMX | 新生代的最大容量大小(KB) |
NGC | 當前新生代的容量大小(KB) |
S0C | 當前新生代中survivor space 0的容量大小(KB) |
S1C | 當前新生代中survivor space 1的容量大小(KB) |
EC | Eden space當前容量的大小(KB) |
OGCMN | 老生代的最小容量大小(KB) |
OGCMX | 老生代的最大容量大小(KB) |
OGC | 當前老生代的容量大小(KB) |
OC | 當前老生代的空間容量大小(KB) |
PGCMN | 持久代的最小容量大小(KB) |
PGCMX | 持久代的最大容量大小(KB) |
PGC | 當前持久代的容量大小(KB) |
PC | 當前持久代的空間容量大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
5. gccause 用於查看垃圾收集的統計情況(這個和-gcutil選項一樣),如果有發生垃圾收集,它還會顯示最後一次及當前正在發生垃圾收集的原因。
列名 | 說明 |
---|---|
LGCC | 最後一次垃圾收集的原因,可能爲“unknown GCCause”、“System.gc()”等 |
GCC | 當前垃圾收集的原因 |
6. gcnew 用於查看新生代垃圾收集的情況
列名 | 說明 |
---|---|
S0C | 當前新生代中survivor space 0的容量大小(KB) |
S1C | 當前新生代中survivor space 1的容量大小(KB) |
S0U | S0已經使用的大小(KB) |
S1U | S1已經使用的大小(KB) |
TT | Tenuring threshold,要了解這個參數,我們需要了解一點Java內存對象的結構,在Sun JVM中,(除了數組之外的)對象都有兩個機器字(words)的頭部。第一個字中包含這個對象的標示哈希碼以及其他一些類似鎖狀態和等標識信息,第二個字中包含一個指向對象的類的引用,其中第二個字節就會被垃圾收集算法使用到。 在新生代中做垃圾收集的時候,每次複製一個對象後,將增加這個對象的收集計數,當一個對象在新生代中被複制了一定次數後,該算法即判定該對象是長週期的對象,把他移動到老生代,這個閾值叫着tenuring threshold。這個閾值用於表示某個/些在執行批定次數youngGC後還活着的對象,即使此時新生的的Survior沒有滿,也同樣被認爲是長週期對象,將會被移到老生代中。 |
MTT | Maximum tenuring threshold,用於表示TT的最大值。 |
DSS | Desired survivor size (KB).可以參與這裏:http://blog.csdn.net/yangjun2/article/details/6542357 |
EC | Eden space當前容量的大小(KB) |
EU | Eden space已經使用的大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
YGCT | 從應用程序啓動到採樣時 Young GC 所用的時間(單位秒) |
7. gcnewcapacity 用於查看新生代的存儲容量情況
列名 | 說明 |
---|---|
NGCMN | 新生代的最小容量大小(KB) |
NGCMX | 新生代的最大容量大小(KB) |
NGC | 當前新生代的容量大小(KB) |
S0CMX | 新生代中SO的最大容量大小(KB) |
S0C | 當前新生代中SO的容量大小(KB) |
S1CMX | 新生代中S1的最大容量大小(KB) |
S1C | 當前新生代中S1的容量大小(KB) |
ECMX | 新生代中Eden的最大容量大小(KB) |
EC | 當前新生代中Eden的容量大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
8. gcold 用於查看老生代及持久代發生GC的情況
列名 | 說明 |
---|---|
PC | 當前持久代容量的大小(KB) |
PU | 持久代使用容量的大小(KB) |
OC | 當前老年代容量的大小(KB) |
OU | 老年代使用容量的大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
FGCT | 從應用程序啓動到採樣時 Full GC 所用的時間(單位秒) |
GCT | 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC |
9. gcoldcapacity 用於查看老生代的容量
列名 | 說明 |
---|---|
OGCMN | 老生代的最小容量大小(KB) |
OGCMX | 老生代的最大容量大小(KB) |
OGC | 當前老生代的容量大小(KB) |
OC | 當前新生代的空間容量大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
FGCT | 從應用程序啓動到採樣時 Full GC 所用的時間(單位秒) |
GCT | 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC |
10. gcpermcapacity 用於查看持久代的容量
列名 | 說明 |
---|---|
PGCMN | 持久代的最小容量大小(KB) |
PGCMX | 持久代的最大容量大小(KB) |
PGC | 當前持久代的容量大小(KB) |
PC | 當前持久代的空間容量大小(KB) |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
FGC | Full GC次數 |
FGCT | 從應用程序啓動到採樣時 Full GC 所用的時間(單位秒) |
GCT | 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC |
11. gcutil 用於查看新生代、老生代及持代垃圾收集的情況
列名 | 說明 |
---|---|
S0 | Heap上的 Survivor space 0 區已使用空間的百分比 |
S1 | Heap上的 Survivor space 1 區已使用空間的百分比 |
E | Heap上的 Eden space 區已使用空間的百分比 |
O | Heap上的 Old space 區已使用空間的百分比 |
P | Perm space 區已使用空間的百分比 |
YGC | 從應用程序啓動到採樣時發生 Young GC 的次數 |
YGCT | 從應用程序啓動到採樣時 Young GC 所用的時間(單位秒) |
FGC | 從應用程序啓動到採樣時發生 Full GC 的次數 |
FGCT | 從應用程序啓動到採樣時 Full GC 所用的時間(單位秒) |
GCT | 從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC |
12. printcompilation HotSpot編譯方法的統計
列名 | 說明 |
---|---|
Compiled | 編譯任務執行的次數 |
Size | 方法的字節碼所佔的字節數 |
Type | 編譯類型 |
Method | 指定確定被編譯方法的類名及方法名,類名中使名“/”而不是“.”做爲命名分隔符,方法名是被指定的類中的方法,這兩個字段的格式是由HotSpot中的“-XX:+PrintComplation”選項確定的。 |
示例
- 1
4.6 jvisualvm(Java Virtual Machine Monitoring, Troubleshooting, and Profiling Tool)
jvisualvm同jconsole都是一個基於圖形化界面的、可以查看本地及遠程的JAVA GUI監控工具,Jvisualvm同jconsole的使用方式一樣,直接在命令行打入Jvisualvm即可啓動,不過Jvisualvm相比,界面更美觀一些,數據更實時。
4.7 jconsole
一個java GUI監視工具,可以以圖表化的形式顯示各種數據。並可通過遠程連接監視遠程的服務器VM。用java寫的GUI程序,用來監控VM,並可監控遠程的VM,非常易用,而且功能非常強。命令行裏打 jconsole,選則進程就可以了。
需要注意的就是在運行jconsole之前,必須要先設置環境變量DISPLAY,否則會報錯誤,Linux下設置環境變量如下:
export DISPLAY=:0.0
4.8 jprofile
JProfiler是一個需要商業授權的全功能的Java剖析工具(profiler),專用於分析J2SE和J2EE應用程序。
它把CPU、執行緒和內存的剖析組合在一個強大的應用中。JProfiler可提供許多IDE整合和應用服務器整合用途。JProfiler直覺式的GUI讓你可以找到效能瓶頸、抓出內存漏失(memory leaks)、並解決執行緒的問題。它讓你得以對heap walker作資源回收器的root analysis,可以輕易找出內存漏失;heap快照(snapshot)模式讓未被參照(reference)的對象、稍微被參照的對象、或在終結(finalization)隊列的對象都會被移除;整合精靈以便剖析瀏覽器的Java外掛功能。
4.9 jca
Java線程分析工具,專業的線程分析工具兼容sun/oracle JDK dump線程堆,圖形化顯示線程概括信息,非常容易的定位問題。
jca是一個類工具 啓動方法:
- 1
4.10 jinfo命令(Java Configuration Info)
jinfo可以輸出並修改運行時的java 進程的opts。用處比較簡單,用於輸出JAVA系統參數及命令行參數。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
4.11 Jdb命令(The Java Debugger)
用來對core文件和正在運行的Java進程進行實時地調試,裏面包含了豐富的命令幫助您進行調試。
4.12 Jstatd命令(Java Statistics Monitoring Daemon)
jstatd是一個基於RMI(Remove Method Invocation)的服務程序,它用於監控基於HotSpot的JVM中資源的創建及銷燬,並且提供了一個遠程接口允許遠程的監控工具連接到本地的JVM執行命令。
jstatd是基於RMI的,所以在運行jstatd的服務器上必須存在RMI註冊中心,如果沒有通過選項”-p port”指定要連接的端口,jstatd會嘗試連接RMI註冊中心的默認端口。後面會談到如何連接到一個默認的RMI內部註冊中心,如何禁止默認的RMI內部註冊中心的創建,以及如何啓動一個外部註冊中心。
參數選項
- 1
- 2
- 3
- 4
安全性
jstatd服務只能監視具有適當的本地訪問權限的JVM,因此jstatd進程與被監控的JVM必須運行在相同的用戶權限中。但是有一些特殊的用戶權限,如基於UNIX(TM)爲系統的root用戶,它有權限訪問系統中所有JVM的資源,如果jstatd進程運行在這種權限中,那麼它可以監視系統中的所有JVM,但是這也帶來了額外的安全問題。
示例
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
4.13 httpwatch
網頁數據分析工具,對客戶端到服務器端的請求,響應數據有效的監控分析。
5. 生產環境示例
5.1 Tomcat7
catalina.sh(只運行一個Tomcat)
- 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進程的GC參數加上如下選項,很多商業版都默認加上了,這對JDK性能提升有很大幫助: