有的同學(xué)雖然寫了一段時間 Java 了,但是對于 JVM 卻不太關(guān)注。有的同學(xué)說,參數(shù)都是團(tuán)隊規(guī)定好的,部署的時候也不用我動手,關(guān)注它有什么用,而且,JVM 這東西,聽上去就感覺很神秘很高深的樣子,還是算了吧。
成都網(wǎng)站建設(shè)、做網(wǎng)站介紹好的網(wǎng)站是理念、設(shè)計和技術(shù)的結(jié)合。創(chuàng)新互聯(lián)擁有的網(wǎng)站設(shè)計理念、多方位的設(shè)計風(fēng)格、經(jīng)驗豐富的設(shè)計團(tuán)隊。提供PC端+手機(jī)端網(wǎng)站建設(shè),用營銷思維進(jìn)行網(wǎng)站設(shè)計、采用先進(jìn)技術(shù)開源代碼、注重用戶體驗與SEO基礎(chǔ),將技術(shù)與創(chuàng)意整合到網(wǎng)站之中,以契合客戶的方式做到創(chuàng)意性的視覺化效果。沒錯,部署的時候可能用不到你親自動手,但是出現(xiàn)問題了怎么辦,難道不用你解決問題嗎,如果對 JVM 了解不夠的話,有些問題可能排查起來就很費(fèi)力,或者根本無法解決。
本篇以 JDK Hotspot 8 為背景,介紹一下 JVM 的常用參數(shù)。建議你在做一些小項目、小 demo 的時候,也把這些參數(shù)加上,加深印象。以我的經(jīng)驗來看,有些知識你剛開始接觸的時候會感覺很難理解,但是沒關(guān)系,萬事開頭難嘛,知識點(diǎn)都是需要消化時間的。第一天不理解,甚至過了一個月也不理解,但是總有那么一刻,你會突然有種茅塞頓開的感覺,感覺一下子通了。最后心里面感謝自己在多少多少天以前能夠開始學(xué)習(xí)并堅持學(xué)習(xí)這些知識點(diǎn)。
只介紹一些常用參數(shù),除了這些常用參數(shù)外,Hotspot 還提供了很多其他的參數(shù),每一個都值得考究。
還是要把內(nèi)存模型圖放在這里,方便理解。
-Xms: 堆的初始值,例如 -Xmx2048,初始堆大小為 2G
-Xmx: 堆的大值,例如 -Xmx2048M,允許大堆內(nèi)存 2G
-Xmn: 新生代大小
-XX:SurvivorRatio:Eden 區(qū)所占比例,默認(rèn)是 8,也就是 80%,例如 -XX:SurvivorRatio=8
最好將 -Xms 和 -Xmx 的值設(shè)置成一樣的值,這樣做是為了防止隨著堆空間使用量增加,會動態(tài)的調(diào)整堆空間大小,有一定的性能損耗,不如開始就設(shè)置成相同的值,來規(guī)避性能損失。
棧參數(shù)
-Xss:棧空間大小,棧是線程獨(dú)占的,所以是一個線程使用??臻g的大小,例如 -Xss256K,如果不設(shè)置此參數(shù),默認(rèn)值是 1M,一般來講設(shè)置成 256K 就足夠了。
Metaspace 參數(shù)
-XX:MetaspaceSize:Metaspace 空間初始大小,如果不設(shè)置的話,默認(rèn)是20.79M,這個初始大小是觸發(fā)首次 Metaspace Full GC 的閾值,例如 -XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize:Metaspace 大值,默認(rèn)不限制大小,但是線上環(huán)境建議設(shè)置,例如
-XX:MaxMetaspaceSize=256M
-XX:MinMetaspaceFreeRatio:最小空閑比,當(dāng) Metaspace 發(fā)生 GC 后,會計算 Metaspace 的空閑比,如果空閑比(空閑空間/當(dāng)前 Metaspace 大小)小于此值,就會觸發(fā) Metaspace 擴(kuò)容。默認(rèn)值是 40 ,也就是 40%,例如 -XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatio:大空閑比,當(dāng) Metaspace 發(fā)生 GC 后,會計算 Metaspace 的空閑比,如果空閑比(空閑空間/當(dāng)前 Metaspace 大小)大于此值,就會觸發(fā) Metaspace 釋放空間。默認(rèn)值是 70 ,也就是 70%,例如 -XX:MaxMetaspaceFreeRatio=70
建議將 MetaspaceSize 和 MaxMetaspaceSize 設(shè)置為同樣大小,避免頻繁擴(kuò)容。
GC 日志
簡單日志
-verbose:gc 或者 -XX:+PrintGC
日志格式:
[GC (Allocation Failure) 7892K->5646K(19456K), 0.0060442 secs] [GC (Allocation Failure) , 0.0066315 secs] [Full GC (Allocation Failure) 19302K->13646K(19456K), 0.0032698 secs]
詳細(xì)日志
#打印詳細(xì)日志 -XX:+PrintGCDetails #打印 GC 的時間點(diǎn) -XX:+PrintGCDateStamps
日志格式:
2019-11-13T14:06:46.099-0800: [GC (Allocation Failure) 2019-11-13T14:06:46.099-0800: [DefNew (promotion failed) : 9180K->9157K(9216K), 0.0084297 secs]2019-11-13T14:06:46.107-0800: [Tenured: 10145K->10145K(10240K), 0.0035768 secs] 13802K->13646K(19456K), [Metaspace: 3895K->3895K(1056768K)], 0.0120887 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] 2019-11-13T14:06:47.243-0800: [Full GC (Allocation Failure) 2019-11-13T14:06:47.244-0800: [Tenured: 10145K->10145K(10240K), 0.0042686 secs] 19304K->19146K(19456K), [Metaspace: 3895K->3895K(1056768K)], 0.0043232 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
以下幾個 GC 日志相關(guān)的參數(shù)打印的內(nèi)容比較多,生產(chǎn)環(huán)境可選擇性開啟,大多數(shù)時候不需要開啟。
GC 前后的堆信息
-XX:+PrintHeapAtGC
{Heap before GC invocations=0 (full 0): def new generation total 9216K, used 7892K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) eden space 8192K, 96% used [0x00000007bec00000, 0x00000007bf3b5200, xxx.... class space used 445K, capacity 462K, committed 512K, reserved 1048576K Heap after GC invocations=1 (full 0): def new generation total 9216K, used 1023K [0x00000007bec00000, xxx... Metaspace used 3892K, capacity 4646K, committed 4864K, reserved 1056768K class space used 445K, capacity 462K, committed 512K, reserved 1048576K }
GC 導(dǎo)致的 Stop the world 時間
-XX:+PrintGCApplicationStoppedTime
Total time for which application threads were stopped: 0.0070384 seconds, Stopping threads took: 0.0000200 seconds
加載類信息
-verbose:class
[Loaded java.net.URLClassLoader$3$1 from /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/rt.jar]
GC 前后的類加載情況
-XX:+PrintClassHistogramBeforeFullGC -XX:+PrintClassHistogramAfterFullGC
num #instances #bytes class name ---------------------------------------------- 1: 140 19016264 [B 2: 2853 226256 [C 3: 138 169072 [I 4: 761 86240 java.lang.Class 5: 2850 68400 java.lang.String 6: 660 41024 [Ljava.lang.Object;
日志輸出到文件
以上參數(shù)配置好之后,默認(rèn)會輸出到控制臺或者服務(wù)指定的統(tǒng)一日志的位置。但是這里還會有服務(wù)的一般性信息日志、錯誤日志等,都混在一起的話會比較亂,所以,一般都會把 jvm 日志單獨(dú)存放。
#GC 活動日志,根據(jù)配置的參數(shù)輸出內(nèi)容 -Xloggc:/Users/fengzheng/jvmlog/gc.log #致命錯誤日志,只有在 jvm 發(fā)生崩潰的時候會輸出 -XX:ErrorFile=/Users/fengzheng/jvmlog/hs_err_pid%p.log
堆溢出現(xiàn)場保留
有些錯誤雖然不會導(dǎo)致 jvm 崩潰,但是對于服務(wù)而言也是非常嚴(yán)重的,比如stackOverflow、OutOfMemoryError,發(fā)生錯誤后,留存現(xiàn)場信息對分析錯誤原因是至關(guān)重要的。jvm 提供了保留堆溢出現(xiàn)場的方法,對于 JDK 8 而言,可能是 heap 溢出,也可能是 Metasapce 溢出。
-XX:HeapDumpPath=/Users/fengzheng/jvmlog -XX:+HeapDumpOnOutOfMemoryError
最后出現(xiàn)異常后,保存的文件格式為 java_pidxxx.hprof,pid 后面是發(fā)生溢出的進(jìn)程 id,之后可以用 VisualVM、JProfiler 等工具打開分析。
設(shè)置垃圾回收器類型
隨著 JDK 版本的升級,可使用的垃圾收集器類型也越來越多了。JDK 8 可使用的垃圾收集器有 7 種,當(dāng)然有點(diǎn)只適用于年輕代,有點(diǎn)只使用于老年代,JDK 8 中最新的垃圾收集器是 G1,可以用于年輕代和老年代。到了 JDK 11,還出了 ZGC。
下圖是 JDK 8 中可使用的垃圾收集器以及它們配合使用的關(guān)系。
Serial、ParNew、Parallel Scavenge 只適用于年輕代,CMS、Serial Old、Parallel Old 只適用于老年代,而 G1 通用于年輕代和老年代。連線表示它們之間可配合使用的關(guān)系,其中 CMS 和 Serial Old 連線的意思是說 Serial Old 會作為 CMS 的后預(yù)案,當(dāng) CMS 發(fā)生 Concurrent Mode Failure 時啟用。
在 JDK 8 中,如果不指定垃圾收集器,默認(rèn)使用參數(shù) -XX:+UseParallelGC,新生代使用 Parallel Scavenge,老年代使用 Serial Old。
-XX:+UseSerialGC:使用 Serial + Serial Old ,運(yùn)行于 client 模式下的默認(rèn)設(shè)置
-XX:+UseConcMarkSweepGC:使用 ParNew+CMS+Serial Old,CMS 垃圾收集器
-XX:+UseParallelGC:Parallel Scavenge + Serial Old,JDK 8 server 模式下的默認(rèn)設(shè)置
-XX:+UseParallelOldGC:Parallel Scavenge + Parallel Old
-XX:+UseG1GC:使用 G1 垃圾收集器
開啟遠(yuǎn)程 JMX 監(jiān)控
除了日志外,當(dāng)我們需要實時查看 JVM 運(yùn)行情況的時候怎么辦,當(dāng)然可以到 JVM 所在服務(wù)器用 jstack、jmap、jinfo 等工具進(jìn)行查看,但是又不夠直觀,這時候就需要開啟 JMX 遠(yuǎn)程功能,使用 jConsole、VisualVM 等工具進(jìn)行監(jiān)控?;蛘咦约洪_發(fā)監(jiān)控平臺,比如我之前就做了一個 web 版的簡易 VisualVm。無意中就做了個 web 版 JVM 監(jiān)控端
開啟參數(shù)如下:
-Dcom.sun.management.jmxremote #指定 jvm 所在服務(wù)器 ip 或域名 -Djava.rmi.server.hostname=192.168.1.1 #指定端口 -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
以上就是JVM中必須掌握的一些參數(shù)的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司其它相關(guān)文章!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。