JVM7、8詳解及優化

原文地址:http://blog.csdn.net/u013980127/article/details/53913994

1. JVM堆內存劃分

這兩天看到下面這篇文章的圖不錯。

一圖讀懂JVM架構解析

JVM-Architecture

1.1 JDK7及以前的版本

JVM7

其中最上一層是Nursery內存,一個對象被創建以後首先被放到Nursery中的Eden內 
存中,如果存活期超兩個Survivor之後就會被轉移到長時內存中(Old Generation)中。

永久內存中存放着對象的方法、變量等元數據信息。通過如果永久內存不夠,就會得到如下錯誤:

Java.lang.OutOfMemoryError: PermGen
  • 1

1.2 JDK8版本

JVM8

JDK8中把存放元數據中的永久內存從堆內存中移到了本地內存(native memory)中,這樣永久內存就不再佔用堆內存,它可以通過自動增長來避免JDK7以及前期版本中常見的永久內存錯誤(java.lang.OutOfMemoryError: PermGen)。

JDK8也提供了一個新的設置Matespace內存大小的參數:

-XX:MaxMetaspaceSize=128m
  • 1

注意:如果不設置JVM將會根據一定的策略自動增加本地元內存空間。如果你設置的元內存空間過小,你的應用程序可能得到以下錯誤:

java.lang.OutOfMemoryError: Metadata space
  • 1

2. JVM參數

-XX 參數被稱爲不穩定參數,此類參數的設置很容易引起JVM性能上的差異。

不穩定參數語法規則:

  1. 布爾類型

    -XX:+<option> '+'表示啓用該選項
    -XX:-<option> '-'表示關閉該選項
    • 1
    • 2
  2. 數字類型

    -XX:<option>=<number>
    
    
    # 可跟隨單位,例如:'m'或'M'表示兆字節;'k'或'K'千字節;'g'或'G'千兆字節。32K與32768是相同大小的。
    
    • 1
    • 2
    • 3
    • 4
    • 5
  3. 字符串類型

    -XX:<option>=<string>
    
    
    # 通常用於指定一個文件、路徑或一系列命令列表。例如:-XX:HeapDumpPath=./dump.core
    
    • 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:+FailOverToOldVerifierJava6新引入選項,默認啓用如果新的Class校驗器檢查失敗,則使用老的校驗器。解決兼容性問題。
關聯選項:-XX:+UseSplitVerifier
-XX:+HandlePromotionFailureJava1.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:-UseSpinningJava1.4.2和1.5需要手動啓用, Java1.6默認已啓用啓用多線程自旋鎖優化。

關聯選項:
-XX:PreBlockSpin=10
-XX:+UseTLABJava1.4.2以前和使用-client選項時:默認關閉, 其餘版本默認啓用啓用線程本地緩存區(Thread Local)
-XX:+UseSplitVerifierJava1.5默認關閉, Java1.6默認啓用使用新的Class類型校驗器 。

關聯選項: 
-XX:+FailOverToOldVerifier
-XX:+UseThreadPriorities默認啓用使用本地線程的優先級。
-XX:+UseVMInterruptibleIO限於solaris, 默認啓用, Java1.6引入在solaris中,允許運行時中斷線程。

2.2 性能選項

選項默認值描述
-XX:+AggressiveOptsJava1.5 引入
默認關閉
Java1.6後默認開啓
開啓編譯器性能優化。
-XX:CompileThreshold=10000默認值:1000通過JIT編譯器,將方法編譯成機器碼的觸發閥值,可以理解爲調用方法的次數,例如調1000次,將方法編譯爲機器碼。 [-client: 1,500]
-XX:LargePageSizeInBytes=4m默認值:4m
amd64位:2m
設置堆內存的內存最大值。
-XX:MaxHeapFreeRatio=70默認70GC後,如果發現空閒堆內存佔到整個預估上限值的70%,則收縮預估上限值。
-XX:MaxNewSize=size1.3.1 Sparc: 32m
1.3.1 x86: 2.5m
新生代佔整個堆內存的最大值。從Java1.4開始, MaxNewSize成爲 NewRatio的一個函數
-XX:MaxPermSize=64mJava1.5以後::64 bit VMs會增大預設值的30%
1.4 amd64::96m
1.3.1 -client: 32m
其他默認 64m
Perm(俗稱方法區)佔整個堆內存的最大值。
-XX:MinHeapFreeRatio=40默認值:40GC後,如果發現空閒堆內存佔到整個預估上限值的40%,則增大上限值。
關聯選項:
-XX:MaxHeapFreeRatio=70
-XX:NewRatio=2Sparc -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=2m5.0以後: 64 bit Vms 會增大預設值的30%
x86: 1m
x86, 5.0以後: 640k
其他:2.125m
新生代預估上限的默認值。
-XX:ReservedCodeCacheSize=32mSolaris 64-bit, amd64, -server x86: 48m 
1.5.0_06之前, Solaris 64-bit 
amd64: 1024m 
其他:32m
設置代碼緩存的最大值,編譯時用。
-XX:SurvivorRatio=8Solaris 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=512Sparc: 512 
Solaris x86: 320 (5.0以前 256) 
Sparc 64 bit: 
1024 Linux amd64: 1024 (5.0 以前 0) 
其他:512.
線程堆棧大小
-XX:+UseBiasedLockingJava1.5 update 6後引入
默認關閉。
Java1.6默認啓用。
啓用偏向鎖
-XX:+UseFastAccessorMethods默認啓用優化原始類型的getter方法性能。
-XX:-UseISM默認啓用啓用solaris的ISM
-XX:+UseLargePagesJava1.5 update 5後引入
默認關閉
Java1.6默認啓用
啓用大內存分頁。 

關聯選項:
-XX:LargePageSizeInBytes=4m
-XX:+UseMPSSJava1.4.1 之前默認關閉
其他版本默認啓用
啓用solaris的MPSS,不能與ISM同時使用。
-XX:+UseStringCache默認開啓緩存常用字符串。
-XX:AllocatePrefetchLines=1默認值:1在使用JIT生成的預讀取指令分配對象後讀取的緩存行數。如果上次分配的對象是一個實例則默認值是1,如果是一個數組則是3
-XX:AllocatePrefetchStyle=1默認值:1預讀取指令的生成代碼風格
0- 無預讀取指令生成 
1-在每次分配後執行預讀取命令 
2-當預讀取指令執行後使用TLAB()分配水印指針來找回入口
-XX:+UseCompressedStringsJava1.6 update 21引入其中,對於不需要16位字符的字符串,可以使用byte[] 而非char[]。對於許多應用,這可以節省內存,但速度較慢(5%-10%)
-XX:+OptimizeStringConcatJava1.6 update 20引入在可能的情況下優化字符串連接操作。

2.3 調試選項

選項默認值描述
-XX:-CITime默認啓用打印JIT編譯器編譯耗時。
-XX:ErrorFile=./hs_err_pid.logJava1.6引入如果JVM crashed,將錯誤日誌輸出到指定文件路徑。
-XX:-ExtendedDTraceProbesJava6引入,限於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:-PrintCommandLineFlagsJava1.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:-PrintGCDetailsJava1.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:-TraceClassLoadingPreorder1.4.2引入,默認關閉按class的引用/依賴順序打印類裝載信息到stdout。不同於 TraceClassLoading,本選項只記 Loading狀態。 
例如: [Loading java.lang.Object from /home/confsrv/jdk1.6.0_14/jre/lib/rt.jar]
-XX:-TraceClassResolution1.4.2引入,默認關閉打印所有靜態類,常量的代碼引用位置。用於debug。 
例如: 
RESOLVE java.util.HashMap java.util.HashMapEntryHashMap.java:209<br>HashMap209java.util.HashMapEntry
-XX:-TraceClassUnloading默認關閉打印class的卸載信息到stdout。記Unloaded狀態。
-XX:-TraceLoaderConstraintsJava1.6 引入,默認關閉打印class的裝載策略變化信息到stdout。
裝載策略變化是實現classloader隔離/名稱空間一致性的關鍵技術。
-XX:+PerfSaveDataToFile默認啓用當java進程因java.lang.OutOfMemoryError 異常或crashed 被強制終止後,生成一個堆快照文件。
-XX:ParallelGCThreads=n默認值:隨JVM運行平臺不同而異配置並行收集器的線程數,即:同時多少個線程一起進行垃圾回收。此值最好配置與處理器數目相等。
-XX:+UseCompressedOops32位默認關閉,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,默認值:8KGC日誌文件切分大小。

3. 垃圾收集器

3.1 串行回收器

3.1.1 新生代串行回收器

特點

  1. 它僅僅使用單線程進行垃圾回收
  2. 它是獨佔式的垃圾回收
  3. 進行垃圾回收時, Java應用程序中的線程都需要暫停(Stop-The-World)
  4. 使用複製算法
  5. 適合CPU等硬件不是很好的場合

設置參數

-XX:+UseSerialGC 指定新生使用新生代串行收集器和老年代串行收集器, 當以client模式運行時, 它是默認的垃圾收集器
  • 1

3.1.2 老年代串行回收器

特點

  1. 同新生代串行回收器一樣, 單線程, 獨佔式的垃圾回收器
  2. 通常老年代垃圾回收比新生代回收要更長時間, 所以可能會使應用程序停頓較長時間

設置參數

-XX:+UseSerialGC 新生代, 老年代都使用串行回收器 
-XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器 
-XX:+UseParallelGC 新生代使用ParallelGC回收器, 老年代使用串行回收器
  • 1
  • 2
  • 3

3.2 並行回收器

3.2.1 新生代ParNew回收器

特點

  1. 將串行回收多線程化
  2. 使用複製算法
  3. 垃圾回收時, 應用程序仍會暫停, 只不過由於是多線程回收, 在多核CPU上,回收效率會高於串行回收器, 反之在單核CPU, 效率會不如串行回收器

設置參數

-XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器 
-XX:+UseConcMarkSweepGC 新生代使用ParNew回收器, 老年代使用CMS回收器 
-XX:ParallelGCThreads=n 指回ParNew回收器工作時的線程數量, cpu核數小時8時, 其值等於cpu數量, 高於8時,可以使用公式(3+((5*CPU_count)/8))
  • 1
  • 2
  • 3

3.2.2 新生代ParallelGC回收器

特點

  1. 同ParNew回收器一樣, 不同的地方在於,它非常關注系統的吞吐量(通過參數控制)
  2. 使用複製算法
  3. 支持自適應的GC調節策略

設置參數

-XX:+UseParallelGC  新生代用ParallelGC回收器, 老年代使用串行回收器 
-XX:+UseParallelOldGC  新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器系統吞吐量的控制: 
-XX:MaxGCPauseMillis=n(單位ms)   設置垃圾回收的最大停頓時間, 
-XX:GCTimeRatio=n(n在0-100之間)  設置吞吐量的大小, 假設值爲n, 那系統將花費不超過1/(n+1)的時間用於垃圾回收 
-XX:+UseAdaptiveSizePolicy  打開自適應GC策略, 在這種模式下, 新生代的大小, eden,survivior的比例, 晉升老年代的對象年齡等參數會被自動調整,以達到堆大小, 吞吐量, 停頓時間之間的平衡點
  • 1
  • 2
  • 3
  • 4
  • 5

3.2.3 老年代ParallelOldGC回收器

特點

  1. 同新生代的ParallelGC回收器一樣, 是屬於老年代的關注吞吐量的多線程併發回收器
  2. 使用標記壓縮算法

設置參數

-XX:+UseParallelOldGC  新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器, 是非常關注系統吞吐量的回收器組合, 適合用於對吞吐量要求較高的系統 
-XX:ParallelGCThreads=n   指回ParNew回收器工作時的線程數量, cpu核數小時8時, 其值等於cpu數量, 高於8時, 可以使用公式(3+((5*CPU_count)/8))
  • 1
  • 2

3.3 CMS回收器(Concurrent Mark Sweep,併發標記清除)

3.3.1 老年代的併發回收器

特點

  1. 是併發回收, 非獨佔式的回收器, 大部分時候應用程序不會停止運行
  2. 針對年老代的回收器
  3. 使用併發標記清除算法, 因此回收後會有內存碎片, 可以使參數設置進行內存碎片的壓縮整理
  4. 與ParallelGC和ParallelOldGC不同, CMS主要關注系統停頓時間

主要步驟

  1. 初始標記
  2. 併發標記
  3. 預清理
  4. 重新標記
  5. 併發清理
  6. 併發重置

注:初始標記與重新標記是獨佔系統資源的,不能與用戶線程一起執行,而其它階段則可以與用戶線程一起執行

設置參數

-XX:-CMSPrecleaningEnabled  關閉預清理, 不進行預清理, 默認在併發標記後, 會有一個預清理的操作,可減少停頓時間 
-XX:+UseConcMarkSweepGC  老年代使用CMS回收器, 新生代使用ParNew回收器 
-XX:ConcGCThreads=n  設置併發線程數量, 
-XX:ParallelCMSThreads=n  同上, 設置併發線程數量, 
-XX:CMSInitiatingOccupancyFraction=n  指定老年代回收閥值, 即當老年代內存使用率達到這個值時, 會執行一次CMS回收,默認值爲68, 設置技巧: (Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100)>=Xmn 
-XX:+UseCMSCompactAtFullCollection  開啓內存碎片的整理, 即當CMS垃圾回收完成後, 進行一次內存碎片整理, 要注意內存碎片的整理並不是併發進行的, 因此可能會引起程序停頓 
-XX:CMSFullGCsBeforeCompation=n  用於指定進行多少次CMS回收後, 再進行一次內存壓縮 
-XX:+CMSParallelRemarkEnabled  在使用UseParNewGC 的情況下, 儘量減少 mark 的時間 
-XX:+UseCMSInitiatingOccupancyOnly  表示只有達到閥值時才進行CMS回收
-XX:+CMSConcurrentMTEnabled  當該標誌被啓用時,併發的CMS階段將以多線程執行,默認開啓
-XX:+CMSIncrementalMode  在增量模式下,CMS 收集器在併發階段,不會獨佔整個週期,
而會週期性的暫停,喚醒應用線程。收集器把併發階段工作,劃分爲片段,安排在次級(minor) 回收之間運行。這對需要低延遲,運行在少量CPU服務器上的應用很有用。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.3.2 Class的回收(永久區的回收)

設置參數

-XX:+CMSClassUnloadingEnabled  開啓回收Perm區的內存, 默認情況下, 是需要觸發一次FullGC 
-XX:CMSInitiatingPermOccupancyFraction=n  當永久區佔用率達到這個n值時,啓動CMS回收, 需上一個參數開啓的情況下使用
  • 1
  • 2

3.4 G1回收器(jdk1.7後全新的回收器, 用於取代CMS)

3.4.1 概述

特點

  1. 獨特的垃圾回收策略, 屬於分代垃圾回收器
  2. 使用分區算法, 不要求eden, 年輕代或老年代的空間都連續
  3. 並行性: 回收期間, 可由多個線程同時工作, 有效利用多核cpu資源
  4. 併發性: 與應用程序可交替執行, 部分工作可以和應用程序同時執行
  5. 分代GC: 分代收集器, 同時兼顧年輕代和老年代
  6. 空間整理: 回收過程中, 會進行適當對象移動, 減少空間碎片
  7. 可預見性: G1可選取部分區域進行回收, 可以縮小回收範圍, 減少全局停頓

主要步驟

  1. 新生代GC
  2. 併發標記週期

    初始標記新生代GC(此時是並行, 應用程序會暫停止)–>根區域掃描–>併發標記–>重新標記(此時是並行, 應用程序會暫停止)–>獨佔清理(此時應用程序會暫停止)–>併發清理

  3. 混合回收

    這個階段即會執行正常的年輕代gc, 也會選取一些被標記的老年代區域進行回收, 同時處理新生代和年老輕

  4. 若需要, 會進行FullGC

    混合GC時發生空間不足
    在新生代GC時, survivor區和老年代無法容納倖存對象時
    以上兩者都會導致一次FullGC產生

設置參數

-XX:+UseG1GC  打開G1收集器開關, 
-XX:MaxGCPauseMillis=n  指定目標的最大停頓時間,任何一次停頓時間超過這個值, G1就會嘗試調整新生代和老年代的比例, 調整堆大小, 調整晉升年齡 
-XX:ParallelGCThreads=n  用於設置並行回收時, GC的工作線程數量 
-XX:InitiatingHeapOccpancyPercent=n  指定整個堆的使用率達到多少時, 執行一次併發標記週期, 默認45, 過大會導致併發標記週期遲遲不能啓動, 增加FullGC的可能, 過小會導致GC頻繁, 會導致應用程序性能有所下降
  • 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相關的設置

  1. System.gc()

    (1)禁用System.gc() 
      -XX:+DisableExplicitGC  禁止程序中調用System.gc(), 加了此參數, 程序若有調用, 返回的空函數調用 
       System.gc()的調用, 會使用FullGC的方式回收整個堆而會忽略CMS或G1等相關回收器 
    (2)System.gc()使用併發回收 
      -XX:+ExplicitGCCinvokesConcurrent   使用併發方式處理顯示的gc, 即開啓後, System.gc()這種顯示GC纔會併發的回收, (CMS, G1)
    • 1
    • 2
    • 3
    • 4
    • 5
  2. 並行GC前額外觸發的新生代GC

    (1)使用並行回收器(UseParallelGC或者UseParallelOldGC)時, 會額外先觸發一個新生代GC, 目的是儘可能減少停頓時間 
    (2)若不需要這種特性, 可以使用以下參數去除 
      -XX:-ScavengeBeforeFullGC   即去除在FullGC之前的那次新生代GC, 原本默認值爲true 
    • 1
    • 2
    • 3
  3. 對象何時進入老年代

    (1)當對象首次創建時, 會放在新生代的eden區, 若沒有GC的介入,會一直在eden區, GC後,是可能進入survivor區或者年老代 
    (2)當對象年齡達到一定的大小 ,就會離開年輕代, 進入老年代, 對象進入老年代的事件稱爲晉升, 而對象的年齡是由GC的次數決定的, 每一次GC,若對象沒有被回收, 則對象的年齡就會加1, 可以使用以下參數來控制新生代對象的最大年齡: 
      -XX:MaxTenuringThreshold=n  假設值爲n , 則新生代的對象最多經歷n次GC, 就能晉升到老年代, 但這個必不是晉升的必要條件 
      -XX:TargetSurvivorRatio=n  用於設置Survivor區的目標使用率,即當survivor區GC後使用率超過這個值, 就可能會使用較小的年齡作爲晉升年齡 
    (3)除年齡外, 對象體積也會影響對象的晉升的, 若對象體積太大, 新生代無法容納這個對象, 則這個對象可能就會直接晉升至老年代, 可通過以下參數使用對象直接晉升至老年代的閾值, 單位是byte 
      -XX:PretenureSizeThreshold  即對象的大小大於此值, 就會繞過新生代, 直接在老年代分配, 此參數只對串行回收器以及ParNew回收有效, 而對ParallelGC回收器無效
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  4. 在TLAB上分配對象(Thread Local Allocation Buffer, 線程本地分配緩存)

    (1)TLAB: TLAB是一個線程專用的內存分配區域, 虛擬機爲線程分配空間, 針對於體積不大的對象, 會優先使用TLAB, 這個可以加速對象的分配, TLAB是默認開啓的, 若要關閉可以使用以下參數關閉 
      -XX:-UseTLAB  關閉TLAB 
      -XX:+UseTLAB  開啓TLAB, 默認也是開啓的 
      -XX:+PrintTLAB  觀察TALB的使用情況 
      -XX:TLABRefillWasteFraction=n  設置一個比率n, 而refill_waste的值就是(TLAB_SIZE/n), 即TLAB空間較小, 大對象無法分配在TLAB,所以會直接分配到堆上,TLAB較小也很容易裝滿, 因此當TLAB的空間不夠分配一個新對象, 就會考慮廢棄當前TLAB空間還是直接分配到堆上, 就會使用此參數進行判斷, 小於refill_waste就允許廢棄, 而新建TLAB來分配對象,而大於refill_waste就直接在堆上分配, 默認是64 
      -XX:+ResizeTLAB  開啓TLAB自動調整大小, 默認是開啓的, 若要關閉把+號換成-號即可 
      -XX:TLABSize=n  設置一個TLAB的大小, 前提先關閉TLAB的自動調整
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

4. 性能調優工具

4.1 jps(Java Virtual Machine Process Status Tool)

主要用來輸出JVM中運行的進程狀態信息。語法格式如下:

jps [options] [hostid]

# hostid語法如下:
[protocol:][[//]hostname][:port][/servername]
protocol - 如果protocol及hostname都沒有指定,那表示的是與當前環境相關的本地協議,如果指定了hostname卻沒有指定protocol,那麼protocol的默認就是rmi。
hostname - 服務器的IP或者名稱,沒有指定則表示本機。
port - 遠程rmi的端口,如果沒有指定則默認爲1099。
Servername - 註冊到RMI註冊中心中的jstatd的名稱。

# 如果不指定hostid就默認爲當前主機或服務器。

# 命令行參數選項
-q 忽略輸出類名、Jar名和傳入main方法的參數
-m 輸出傳入main方法的參數
-l 輸出main類或Jar的全限名
-v 輸出傳入JVM的參數
-V 輸出通過標記的文件傳遞給JVM的參數(.hotspotrc文件,或者是通過參數-XX:Flags=<filename>指定的文件)
-J 用於傳遞jvm選項到由javac調用的java加載器中,例如,“-J-Xms48m”將把啓動內存設置爲48M,使用-J選項可以非常方便的向基於Java的開發的底層虛擬機應用程序傳遞參數。
  • 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進程內的線程堆棧信息。語法格式如下:

jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip

# 命令行參數選項說明如下:
-l 長列表,會打印出額外的鎖信息,在發生死鎖時可以用jstack -l pid來觀察鎖持有情況
-m mixed mode,不僅會輸出Java堆棧信息,還會輸出C/C++堆棧信息(比如Native方法)
-F 當’jstack [-l] pid’沒有相應的時候強制打印棧信息
-h | -help打印幫助信息
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

jstack可以定位到線程堆棧,根據堆棧信息我們可以定位到具體代碼,所以它在JVM性能調優中使用得非常多。

4.3 jmap(Java Memory Map)

jmap用來查看堆內存使用狀況,一般結合jhat使用。jmap語法格式如下:

如果運行在64位JVM上,可能需要指定-J-d64命令選項參數。

jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip

# 參數說明
executable            產生core dump的java可執行程序
core                  將被打印信息的core dump文件
remote-hostname-or-ip 遠程debug服務的主機名或ip
server-id             唯一id,假如一臺主機上多個遠程debug服務
pid                   需要被打印配相信息的java進程id,可以用jps查問

# 基本參數
-dump:[live,]format=b,file=<filename> 使用hprof二進制形式,輸出jvm的heap內容到文件=. live子選項是可選的,假如指定live選項,那麼只輸出活的對象到文件
-finalizerinfo 打印正等候回收的對象的信息
-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情況
-histo[:live] 打印每個class的實例數目,內存佔用,類全名信息. VM的內部類名字開頭會加上前綴”*”. 如果live子參數加上後,只統計活的對象數量
-permstat 打印classload和jvm heap長久層的信息. 包含每個classloader的名字,活潑性,地址,父classloader和加載的class數量. 另外,內部String的數量和佔用內存數也會打印出來
-F 強迫.在pid沒有相應的時候使用-dump或者-histo參數. 在這個模式下,live子參數無效
-h | -help 打印輔助信息
-J 傳遞參數給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進行離線分析的工具,它可以對不同虛擬機中導出的heap信息文件進行分析

# 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這種參數指定最大堆內存

# 在瀏覽器中輸入主機地址:9998查看
  • 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區中容量及分配情況等

語法:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

generalOption - 單個的常用的命令行選項,如-help, -options, 或 -version。
outputOptions -一個或多個輸出選項,由單個的statOption選項組成,可以和-t, -h, and -J等選項配合使用。

statOption 根據jstat統計的維度不同,可以使用如下表中的選項進行不同維度的統計,不同的操作系統支持的選項可能會不一樣,可以通過-options選項,查看不同操作系統所支持選項

-h n          用於指定每隔幾行就輸出列頭,如果不指定,默認是隻在第一行出現列頭。
-J javaOption 用於將給定的javaOption傳給java應用程序加載器,例如,“-J-Xms48m”將把啓動內存設置爲48M
-t n          用於在輸出內容的第一列顯示時間戳,這個時間戳代表的時JVM開始啓動到現在的時間
vmid          VM的進程號,即當前運行的java進程號
interval      間隔時間,單位可以是秒或者毫秒,通過指定s或ms確定,默認單位爲毫秒
count         打印次數,如果缺省則打印無數次
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

統計維度與輸出

  1. 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)
ECEden space當前容量的大小(KB)
EUEden space容量使用的大小(KB)
OCOld space當前容量的大小(KB)
OUOld space使用容量的大小(KB)
PCPermanent space當前容量的大小(KB)
PUPermanent space使用容量的大小(KB)
YGC從應用程序啓動到採樣時發生 Young GC 的次數
YGCT從應用程序啓動到採樣時 Young GC 所用的時間(秒)
FGC從應用程序啓動到採樣時發生 Full GC 的次數
FGCT從應用程序啓動到採樣時 Full GC 所用的時間(秒)
GCTT從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC

4. gccapacity 用於查看新生代、老生代及持久代的存儲容量情況

列名說明
NGCMN新生代的最小容量大小(KB)
NGCMX新生代的最大容量大小(KB)
NGC當前新生代的容量大小(KB)
S0C當前新生代中survivor space 0的容量大小(KB)
S1C當前新生代中survivor space 1的容量大小(KB)
ECEden 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)
S0US0已經使用的大小(KB)
S1US1已經使用的大小(KB)
TTTenuring threshold,要了解這個參數,我們需要了解一點Java內存對象的結構,在Sun JVM中,(除了數組之外的)對象都有兩個機器字(words)的頭部。第一個字中包含這個對象的標示哈希碼以及其他一些類似鎖狀態和等標識信息,第二個字中包含一個指向對象的類的引用,其中第二個字節就會被垃圾收集算法使用到。

在新生代中做垃圾收集的時候,每次複製一個對象後,將增加這個對象的收集計數,當一個對象在新生代中被複制了一定次數後,該算法即判定該對象是長週期的對象,把他移動到老生代,這個閾值叫着tenuring threshold。這個閾值用於表示某個/些在執行批定次數youngGC後還活着的對象,即使此時新生的的Survior沒有滿,也同樣被認爲是長週期對象,將會被移到老生代中。
MTTMaximum tenuring threshold,用於表示TT的最大值。
DSSDesired survivor size (KB).可以參與這裏:http://blog.csdn.net/yangjun2/article/details/6542357
ECEden space當前容量的大小(KB)
EUEden 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 的次數
FGCFull GC次數
FGCT從應用程序啓動到採樣時 Full GC 所用的時間(單位秒)
GCT從應用程序啓動到採樣時用於垃圾回收的總時間(單位秒),它的值等於YGC+FGC

11. gcutil 用於查看新生代、老生代及持代垃圾收集的情況

列名說明
S0Heap上的 Survivor space 0 區已使用空間的百分比
S1Heap上的 Survivor space 1 區已使用空間的百分比
EHeap上的 Eden space 區已使用空間的百分比
OHeap上的 Old space 區已使用空間的百分比
PPerm 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”選項確定的。

示例

jstat -gc 1618 250 4
  • 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是一個類工具 啓動方法:

java -jar jca433.jar
  • 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內部註冊中心的創建,以及如何啓動一個外部註冊中心。

參數選項

-nr 如果RMI註冊中心沒有找到,不會創建一個內部的RMI註冊中心。
-p port RMI註冊中心的端口號,默認爲1099-n rminame 默認爲JStatRemoteHost;如果同一臺主機上同時運行了多個jstatd服務,rminame可以用於唯一確定一個jstatd服務;這裏需要注意一下,如果開啓了這個選項,那麼監控客戶端遠程連接時,必須同時指定hostid及vmid,纔可以唯一確定要連接的服務,這個可以參看jps章節中列出遠程服務器上Java進程的示例。
-J 用於傳遞jvm選項到由javac調用的java加載器中,例如,“-J-Xms48m”將把啓動內存設置爲48M,使用-J選項可以非常方便的向基於Java的開發的底層虛擬機應用程序傳遞參數。
  • 1
  • 2
  • 3
  • 4

安全性

jstatd服務只能監視具有適當的本地訪問權限的JVM,因此jstatd進程與被監控的JVM必須運行在相同的用戶權限中。但是有一些特殊的用戶權限,如基於UNIX(TM)爲系統的root用戶,它有權限訪問系統中所有JVM的資源,如果jstatd進程運行在這種權限中,那麼它可以監視系統中的所有JVM,但是這也帶來了額外的安全問題。

示例

# 使用內部RMI註冊中心(默認端口是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  

# 禁止內部RMI註冊中心的創建
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

網頁數據分析工具,對客戶端到服務器端的請求,響應數據有效的監控分析。

5. 生產環境示例

5.1 Tomcat7

catalina.sh(只運行一個Tomcat)

# 8G內存
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內存(垃圾回收略)
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內存(垃圾回收略)
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進程的GC參數加上如下選項,很多商業版都默認加上了,這對JDK性能提升有很大幫助:

-XX:CMSInitiatingOccupancyFraction=70
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseConcMarkSweepGC
-XX:-CMSConcurrentMTEnabled
-XX:+CMSIncrementalMode
-Djava.net.preferIPv4Stack=true


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章