深入JVM-常用Java虛擬機(jī)參數(shù)

一、跟蹤調(diào)試參數(shù)

1.1 跟蹤垃圾回收-讀懂虛擬機(jī)日志

Java的一大特色就是支持自動(dòng)的垃圾回收(GC),但是有時(shí)候,如果垃圾回收頻繁出現(xiàn),或者占用了太長(zhǎng)的CPU時(shí)間,就不得不引起重視。此時(shí),就需要一些跟蹤參數(shù)來進(jìn)一步甄別垃圾回收器的效率和效果。

最簡(jiǎn)單的一個(gè)GC參數(shù)是-XX:+PrintGC,使用這個(gè)參數(shù)啟動(dòng)Java虛擬機(jī)后,只要遇到GC,就會(huì)打印日志。

如果需要更加詳細(xì)的信息,則可以使用-XX:+PrintGCDetails參數(shù)。他的輸出可能如下:

GC 詳細(xì)輸出

從這個(gè)輸出可以看到,系統(tǒng)經(jīng)歷了3次GC,第一次僅為新生代GC,回收的效果是新生代從回收前的8MB左右降到了1M左右。整個(gè)堆從22MB左右降到了17MB。

第二次為Full GC,它同時(shí)回收了新生代、老年代和永久區(qū)。從日志顯示,新生代在這次GC中沒有釋放空間(嚴(yán)格來說,這是GC日志的一個(gè)小bug,事實(shí)上,在這次Full GC完成后,新生代被清空,由于GC日志輸出時(shí)機(jī)的關(guān)系,各個(gè)版本的JDK日志多少有些不太精確的地方),老年代從16MB降到了13MB。整個(gè)堆大小從26MB左右降到了13MB左右(這個(gè)大小完全與老年代實(shí)際大小相等,因此可以推斷,新生代實(shí)際上已被清空)。永久區(qū)的大小沒有變化。日志的最后,顯示了GC花費(fèi)的時(shí)間,其中user表示用戶態(tài)CPU耗時(shí),sys表示系統(tǒng)CPU耗時(shí),real表示GC實(shí)際經(jīng)歷的時(shí)間。

如果需要更全面的堆信息,還可以使用參數(shù)-XX:+PrintHeapAtGC。他會(huì)在每次GC前后分別打印堆的信息。

如果需要分析GC發(fā)生的時(shí)間,還可以使用-XX:+PrintGCTimeStamps參數(shù),該參數(shù)會(huì)在每次GC發(fā)生時(shí),額外輸出GC發(fā)生的時(shí)間,該輸出時(shí)機(jī)為虛擬機(jī)啟動(dòng)后的時(shí)間偏移量。

默認(rèn)情況下,GC的日志會(huì)在控制臺(tái)輸出,這不便于后續(xù)分析和定位問題。為此,虛擬機(jī)允許將GC日志以文件的形式輸出,可以使用參數(shù)-Xloggc指定。

1.2 類加載/卸載的跟蹤

一般情況下,系統(tǒng)加載的類存在于文件系統(tǒng)中,以jar的形式打包或者以class文件的形式存在,可以直接通過文件系統(tǒng)查看。但是隨著動(dòng)態(tài)代理、AOP等技術(shù)的普遍使用,系統(tǒng)也ji'ke'neng極可能在運(yùn)行時(shí)動(dòng)態(tài)生成某些類,這些類相對(duì)比較隱蔽,無法通過文件系統(tǒng)找到。

可以使用參數(shù)-verbose:class跟蹤類的加載和卸載,也可以單獨(dú)使用參數(shù)-XX:+TraceClassLoading跟蹤類的加載,使用參數(shù)-XX:+TraceClassUnloading跟蹤類的卸載。

Java虛擬機(jī)還允許研發(fā)人員在運(yùn)行時(shí)打印、查看系統(tǒng)中類的分布情況,只要在系統(tǒng)啟動(dòng)時(shí)加上-XX:+PrintClassHistogram參數(shù),然后在Java控制臺(tái)按下Ctrl+Break組合鍵,控制臺(tái)就會(huì)顯示當(dāng)前的類信息柱狀圖。

1.3 系統(tǒng)參數(shù)查看

參數(shù)-XX:+PrintVMOptions可以在程序運(yùn)行時(shí),打印虛擬機(jī)接收到的命令行顯式參數(shù)。

參數(shù)-XX:+PrintCommandLineFlags可以打印傳遞給虛擬機(jī)的顯式和隱式參數(shù)。

二、學(xué)習(xí)堆的配置參數(shù)

2.1 最大堆和初始堆的設(shè)置

  • Xms:初始堆
  • Xmx:最大堆

在實(shí)際工作中,也可以直接將初始堆-Xms和最大堆-Xmx設(shè)置相等,這樣好處是可以減少程序運(yùn)行時(shí)進(jìn)行的垃圾回收次數(shù),從而提高程序的性能。

2.2 新生代的配置

參數(shù)-Xmn可以用于設(shè)置新生代的大小。設(shè)置一個(gè)較大的新生代會(huì)減小老年代的大小,這個(gè)參數(shù)對(duì)系統(tǒng)性能以及GC行為有很大的影響,新生代的大小一般設(shè)置為整個(gè)堆空間的1/3到1/4左右。

參數(shù)-XX:SurvivorRatio用來設(shè)置新生代中eden空間和from/to空間的比例關(guān)系,他的含義如下:

-XX:SurvivorRatio=eden/from=eden/to

實(shí)際工作中,堆分布的基本策略是:盡可能將對(duì)象預(yù)留在新生代,減少老年代GC的次數(shù)。

除了可以使用-Xmn指定新生代的絕對(duì)大小外,還可以使用參數(shù)-XX:NewRatio來設(shè)置新生代和老年大的比例,他的含義如下:

-XX:NewRatio=老年代/新生代
堆的分配參數(shù)示意圖

2.3 堆溢出處理

在Java程序的運(yùn)行過程中,如果堆空間不足,則有可能拋出內(nèi)存溢出錯(cuò)誤(OutOfMemory),簡(jiǎn)稱OOM。一旦發(fā)生這類問題,系統(tǒng)就會(huì)被迫退出。如果發(fā)生在生產(chǎn)環(huán)節(jié),可能會(huì)引起嚴(yán)重的業(yè)務(wù)中斷。為了不斷改善系統(tǒng),避免或減少這類錯(cuò)誤的發(fā)生,需要在發(fā)生錯(cuò)誤時(shí),獲得盡可能多的現(xiàn)場(chǎng)信息。Java虛擬機(jī)提供了參數(shù)-XX:+HeapDumpOnOutOfMemoryError,使用該參數(shù),可以再內(nèi)存溢出時(shí)導(dǎo)出整個(gè)堆信息。和他配合使用的還有-XX:HeapDumpPath,可以指定導(dǎo)出堆的存放路徑。

三、非堆內(nèi)存的參數(shù)配置

3.1 方法區(qū)配置

方法區(qū)主要存放類的元信息。

在JDK1.6和JDK 1.7等版本中,可以使用-XX:PermSize和-XX:MaxPermSize配置永久區(qū)大小。其中-XX:PermSize表示初始的永久區(qū)大小,-XX:MaxPermSize表示最大永久區(qū)。

在JDK 1.8中,永久區(qū)被徹底移除,使用了新的元數(shù)據(jù)區(qū)存放類的元數(shù)據(jù)。默認(rèn)情況下,元數(shù)據(jù)區(qū)只受系統(tǒng)可用內(nèi)存的限制,但依然可以使用參數(shù)-XX:MaxMetaspaceSize指定元數(shù)據(jù)區(qū)的最大可用值。

3.2 棧配置

通過-Xss指定線程的棧大小。

3.3 直接內(nèi)存配置

最大可以直接內(nèi)存可以使用參數(shù)-XX:MaxDirectMemorySize設(shè)置,如不設(shè)置,默認(rèn)值為最大dui堆空間,即-Xmx。當(dāng)直接內(nèi)存使用量達(dá)到-XX:MaxDirectMemorySize時(shí),就會(huì)觸發(fā)垃圾回收,如果垃圾回收不能有效釋放足夠空間,直接內(nèi)存溢出依然會(huì)引起系統(tǒng)的OOM。

四、虛擬機(jī)的工作模式

目前Java虛擬機(jī)支持Client和Server兩種運(yùn)行模式。默認(rèn)情況下,虛擬機(jī)會(huì)根據(jù)當(dāng)前計(jì)算機(jī)系統(tǒng)環(huán)境自動(dòng)選擇運(yùn)行模式。使用-version參數(shù)可以查看當(dāng)前的模式,如下:

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

與Client模式相比,Server模式啟動(dòng)較慢,因?yàn)镾erver模式會(huì)嘗試收集更多的系統(tǒng)性能信息,使用更復(fù)雜的優(yōu)化算法對(duì)程序進(jìn)行優(yōu)化。因此,當(dāng)系統(tǒng)完全啟動(dòng)并進(jìn)入運(yùn)行穩(wěn)定期后,Server模式的執(zhí)行速度會(huì)遠(yuǎn)遠(yuǎn)快于Client模式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容