JVM的那些常用參數以及命令

簡介

java啓動參數共分爲三類

  • 其一是標準參數(-),所有的JVM實現都必須實現這些參數的功能,而且向後兼容
  • 其二是非標準參數(-X),默認jvm實現這些參數的功能,但是並不保證所有jvm實現都滿足,且不保證向後兼容
  • 其三是非Stable參數(-XX),此類參數各個jvm實現會有所不同,將來可能會隨時取消,需要慎重使用

調試參數

打印啓動參數

可以查看默認參數

java -XX:+PrintCommandLineFlags -version

打印GC日誌

不要用XX:+UseGCLogFileRotation ,這個會丟失舊的日誌文件,而且重啓會覆蓋當前日誌文件:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/GCEASY/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M

應該用下面這個

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/GCEASY/gc-%t.log

打印ClassLoader日誌

這個參數會在控制檯打印所有類加載/卸載信息

-XX:+TraceClassLoading -XX:+TraceClassUnloading

OOM時Dump內存

 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof

OOM時執行腳本(比如重啓)

 -XX:OnOutOfMemoryError=/scripts/restart-myapp.sh

打印JIT時間

-XX:-CITime

方法被編譯時打印相關信息

-XX:-PrintCompilation

內存類

JVM設置內存的單位默認是字節(不加單位的情況下)。

也可以在大小後面增加單位,例如:

-Xmn256m
-Xmn262144k
-Xmn268435456

設置初始新生代大小

-XX:NewSize=2G(也可以是2M)

設置最大新生代大小

-XX:MaxNewSize=2G(也可以是2M)

注意:-Xmn優先級大於-XX:NewRatio

設置Eden/Survivor比例

表示兩個Survivor和Edgen區的比,8表示兩個Survivor:Eden=2:8,即一個Survivor佔新生代的1/10。

計算方式爲:

Survivor Size(1) = Young Generation Size / (2+<SurvivorRatio)
Eden Size = Young Generation Size / (2+SurvivorRatio) * SurvivorRatio

配置:

-XX:SurvivorRatio=8

8也是默認的比例,不過這個比例在Parallel Scavenge(新生代並行回收器,JDK5以後的默認新生代回收器)回收器下是動態的,運行時會出現Eden/Survivor比例和配置的不同。

由於與吞吐量關係密切,Parallel Scavenge收集器也經常稱爲“吞吐量優先”收集器。除上述兩個參數之外,Parallel Scavenge收集器還有一個參數-XX:+UseAdaptiveSizePolicy值得關注。這是一個開關參數,當這個參數打開之後,就不需要手工指定新生代的大小(-Xmn)、Eden與Survivor區的比例(-XX:SurvivorRatio)、晉升老年代對象年齡(-XX:PretenureSizeThreshold)等細節參數了,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量,這種調節方式稱爲GC自適應的調節策略(GC Ergonomics)[插圖]。如果讀者對於收集器運作原來不太瞭解,手工優化存在困難的時候,使用Parallel Scavenge收集器配合自適應調節策略,把內存管理的調優任務交給虛擬機去完成將是一個不錯的選擇。只需要把基本的內存數據設置好(如-Xmx設置最大堆),然後使用MaxGCPauseMillis參數(更關注最大停頓時間)或GCTimeRatio (更關注吞吐量)參數給虛擬機設立一個優化目標,那具體細節參數的調節工作就由虛擬機完成了。自適應調節策略也是Parallel Scavenge收集器與ParNew收集器的一個重要區別。

https://docs.oracle.com/javas...

設置老年代大小

老年代大小無法直接設置,只能通過堆大小+分配比例進行調整

#設置新老一代大小之間的比率。默認值爲2。2表示New Size:Old Size=1:2,則新生代佔堆大小的1/3,老年代佔堆大小的2/3
-XX:NewRatio=2

新生代老年代大小計算方式爲:

New Size = Heap Size / NewRatio + 1
Old Size = (Heap Size / NewRatio + 1) * NewRatio

設置永久代(PermGen/MetaSpace)大小

#設置分配給永久生成的空間,如果超出該空間,則會觸發垃圾回收。此選項在JDK 8中已棄用,並由-XX:MetaspaceSize選項取代。
-XX:PermSize=size
#設置最大永久生成空間大小(以字節爲單位)。此選項在JDK 8中已棄用,並由-XX:MaxMetaspaceSize選項取代。
-XX:MaxPermSize=size

#設置分配的Metaspace的大小,Metaspace將在首次超過垃圾收集時觸發垃圾收集。 垃圾收集的閾值取決於使用的元數據量而增加或減少。 默認大小取決於平臺。
-XX:MetaspaceSize=size

#設置可以分配給Metaspace的最大本機內存。 默認情況下,大小不受限制。 應用程序的Metaspace量取決於應用程序本身,其他正在運行的應用程序以及系統上可用的內存量
-XX:MaxMetaspaceSize=size

初始大小和最大值的區別

初始值(比如-Xms)爲JVM啓動是向操作系統申請的內存大小(malloc),最大值(比如-Xmx)表示,當使用的內存超過初始值後擴容的最大值

PS: JVM配置了多少內存並不是說啓動後就會佔用多少物理內存,因爲操作系統的內存分配是惰性的。對於已申請的內存雖然會分配地址空間,但並不會直接佔用物理內存,真正使用的時候纔會映射到實際的物理內存。

GC類

image

這裏說一下PermGen/Metaspace的GC,沒有查到官方資料說永久代的固定垃圾回收器,但是在stackoverflow上有人回答到:

所有垃圾回收器都會回收永久代,包括PS/CMS,但並不是每個GC週期都會清理永久代。

這個不用糾結,看GC日誌裏清理的信息即可。

Serial/Serial Old

最古老的,單線程,獨佔式,成熟,每次GC會STW,適合單CPU 服務器

Serial是一個新生代收集器,Serial Old是Serial收集器的的老年代版本

新生代和老年代都用串行收集器

-XX:+UseSerialGC

新生代使用ParallerGC,老年代使用Serial Old

-XX:+UseParallelGC

ParNew

和Serial基本沒區別,唯一的區別:多線程,多CPU的,停頓時間比Serial少

新生代使用ParNew,老年代使用Serial Old

-XX:+UseParNewGC(在Java 8中已棄用,在Java 9中已刪除)

Parallel Scavenge(ParallerGC)/Parallel Old

關注吞吐量的垃圾收集器,高吞吐量則可以高效率地利用CPU時間,儘快完成程序的運算任務,主要適合在後臺運算而不需要太多交互的任務。

所謂吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間),虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。

Parallel Scavenge是一個新生代收集器,Parallel Old是Parallel Scavenge收集器的的老年代版本

新生代使用ParallerGC,老年代使用Parallel Old

-XX:+UseParallelGC
#等價於
-XX:+UseParallelOldGC

Concurrent Mark Sweep (CMS)

CMS(Concurrent Mark Sweep),收集器是一種以獲取最短回收停頓時間爲目標的收集器,一個老年代垃圾回收器。目前很大一部分的Java應用集中在互聯網站或者B/S系統的服務端上,這類應用尤其重視服務的響應速度,希望系統停頓時間最短,以給用戶帶來較好的體驗。CMS收集器就非常符合這類應用的需求。

新生代使用ParNew,老年代的用CMS

-XX:+UseConcMarkSweepGC

G1

使用G1收集器

-XX:+UseG1GC

垃圾回收器的組合

命令 新生代回收器&算法 老年代回收器&算法 備註
-XX:+UseSerialGC Serial收集器 Serial Old收集器
-XX:+UseG1GC G1收集器 G1收集器
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy ParallerGC Paraller Old 新生代比例自適應調整
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseAdaptiveSizePolicy ParallerGC Paraller Old 新生代比例不自動調整
-XX:+UseParNewGC ParNew Serial Old Java8廢棄,Java9移除
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC ParNew CMS
-XX:+UseConcMarkSweepGC -XX:-UseParNewGC Serial CMS Java8廢棄,Java9移除

下面是一些缺省的寫法

命令 等同於上表
-XX:+UseParallelGC -XX:+UseParallelGC -XX:+UseParallelOldGC
-XX:+UseParallelOldGC -XX:+UseParallelGC -XX:+UseParallelOldGC
-Xincgc (Java8廢棄,Java9移除) -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

常用JVM參數組合

JDK7

JAVA_MEM_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "
JAVA_DEBUG_OPTS=" -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/GCEASY/gc-%t.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof -XX:OnOutOfMemoryError=/scripts/restart-myapp.sh "

JDK8

JAVA_MEM_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:MetaspaceSize=256m -Xss1024m -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "
JAVA_DEBUG_OPTS=" -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/GCEASY/gc-%t.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof -XX:OnOutOfMemoryError=/scripts/restart-myapp.sh "

關於G1,雖然說JDK8中已經支持G1了,但是並不是說一定需要。

G1的重要特點是爲用戶的應用程序的提供一個低GC延時和大內存GC的解決方案,適用於大內存場景(官方推薦堆6G以上)

如果程序正在使用CMS或ParallelOld垃圾回收器,並且具有一個或多個以下特徵,那麼則可以考慮升級爲G1:

  • Full GC持續時間太長或太頻繁
  • 對象分配率或年輕代升級老年代很頻繁
  • 垃圾收集時間或壓縮暫停(超過0.5至1秒)時間過長

PS:如果正在使用CMS或ParallelOld收集器,並且程序沒有遇到長時間的垃圾收集暫停,那麼就不需要升級到G1

參考

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