jvm 参数_6个提高性能的JVM参数
截止到2020年五月,JVM中僅僅只是關(guān)于垃圾回收和內(nèi)存相關(guān)的參數(shù)就已經(jīng)超過600個(gè)。如果算上其他方面的參數(shù),JVM相關(guān)的總參數(shù)能輕松超過1000個(gè)。參數(shù)太多了,弄得人很懵逼。在這邊文章中,我們只選取了7個(gè)比較重要,且有用的JVM參數(shù)來介紹。
-Xmx 和 -XX:MaxMetaspaceSize
-Xmx可能是最重要最常用的JVM參數(shù)了。-Xmx用來定義能分配給應(yīng)用的最大堆空間大小。你可以像這樣使用:
-Xmx2g堆空間大小直接決定著應(yīng)用性能。但是隨之而來的問題是,對(duì)于一個(gè)應(yīng)用,應(yīng)該設(shè)置多大的堆空間是合理的?我應(yīng)該為我的應(yīng)用設(shè)置一個(gè)大的堆空間,還是一個(gè)相對(duì)較小的?答案是:“看情況”,這個(gè)問題,另開一篇文章專門探討。
這里只提示一點(diǎn),將-Xmx和-Xms設(shè)置為相同,能獲得更好的性能。
元空間是對(duì)JVM規(guī)范中方法區(qū)的實(shí)現(xiàn),用于存儲(chǔ)JVM中的元數(shù)據(jù)信息,比如類定義,方法定義等。在默認(rèn)情況下,元空間使用的是本地內(nèi)存空間,所以理論上講,元空間地址是沒有上限的,他受限于機(jī)器的內(nèi)存大小,內(nèi)存尋址空間大小等??梢酝ㄟ^以下參數(shù)來指定元空間的大小:
-XX:MaxMetaspaceSize=512m //設(shè)置元空間最大空間-XX:MetaspaceSize //初始元空間大小對(duì)于-XX:MetaspaceSize來說,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間,就適當(dāng)降低該值;如果釋放了很少的空間,那么在不超過MaxMetaspaceSize時(shí),適當(dāng)提高該值。
另:除了上面兩個(gè)指定大小的選項(xiàng)以外,還有兩個(gè)與 GC 相關(guān)的屬性:
-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空間容量的百分比,減少為分配空間所導(dǎo)致的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空間容量的百分比,減少為釋放空間所導(dǎo)致的垃圾收集
GC回收器類型
截止目前為止,在OpenJDK中,一共提供了7種類型的GC【這里注意區(qū)分一下GC回收器類型和GC回收算法】:
- Serial GC
- Parallel GC
- Concurrent Mark & Sweep GC
- G1 GC
- Shenandoah GC
- Z GC
- Epsilon GC
如果沒有特別的指定GC回收器,JVM會(huì)使用默認(rèn)的,到Java8,Parallel GC是默認(rèn)回收器,從Java9之后,G1 GC是默認(rèn)的GC回收器。
使用何種GC回收器,對(duì)于應(yīng)用的性能表現(xiàn)起著至關(guān)重要的作用。 從測(cè)試數(shù)據(jù)來看,Z GC有非常不錯(cuò)的表現(xiàn)。如果你的應(yīng)用運(yùn)行在JVM11以上,我們建議優(yōu)先考慮使用Z GC(-XX:+UseZGC)。
下表中列出了不同GC算法及其對(duì)應(yīng)的開啟參數(shù):
- Serial GC -XX:+UseSerialGC
- Parallel GC -XX:+UseParallelGC
- Concurrent Market & Sweep (CMS) GC -XX:+UseConcMarkSweepGC
- G1 GC -XX:+UseG1GC
- Shenandoah GC -XX:+UseShenandoahGC
- Z GC -XX:+UseZGC
- Epsilon GC -XX:+UseEpsilonGC
Enable GC Logging
GC日志中包含了包括垃圾回收事件,內(nèi)存空間情況,時(shí)間間隔等等??梢允褂孟旅娴腏VM參數(shù)來開啟GC日志。
JDK8及其之前:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:{file-path}JDK9及之后:
-Xlog:gc*:file={file-path}一個(gè)詳細(xì)例子:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/workspace/myAppgc.log-Xlog:gc*:file=/opt/workspace/myAppgc.log一般情況下,GC日志主要用來調(diào)整GC性能。然而,GC日志中也包含了很多微觀指標(biāo)。這些指標(biāo)可用于預(yù)測(cè)應(yīng)用程序的可用性和性能。在這里,我們只舉一個(gè)例子:“GC Throughput(GC吞吐量)”。GC吞吐量是應(yīng)用程序處理應(yīng)用事務(wù)所花費(fèi)的時(shí)間與處理GC活動(dòng)所花費(fèi)的時(shí)間之比。比如應(yīng)用的GC吞吐量是98%,這意味著應(yīng)用程序?qū)?8%的時(shí)間花在處理應(yīng)用活動(dòng)上,剩下的2%花在GC活動(dòng)上。
接下來看一個(gè)健康的JVM的堆使用圖:
你可以看到一個(gè)完美的鋸齒圖案??梢钥吹降?#xff0c;當(dāng)運(yùn)行完整的GC(紅色三角形)時(shí),內(nèi)存利用率下降到了底部。再來看一個(gè)有問題的JVM堆使用圖:
注意圖案的右側(cè)區(qū)域,及時(shí)GC不斷的運(yùn)行,內(nèi)存利用率仍然沒有明顯下降。這就是一個(gè)出現(xiàn)了內(nèi)存問題的典型跡象。
當(dāng)我們更仔細(xì)的分析這個(gè)圖片,我們可以看到,在8點(diǎn)左右的時(shí)間,完全GC開始重復(fù)出現(xiàn),知道8點(diǎn)45左右,應(yīng)用出現(xiàn)了OOM異常。8點(diǎn)之前,GC的吞吐量在99%左右,但是在8點(diǎn)之后,GC的吞吐量掉到了60%,因?yàn)榇罅恐貜?fù)GC的動(dòng)作出現(xiàn),讓應(yīng)用已經(jīng)沒有太多時(shí)間處理應(yīng)用的正常事務(wù)。一種主動(dòng)的措施,如果當(dāng)發(fā)現(xiàn)GC吞吐量開始下降的時(shí)候,我們可以從負(fù)載平衡群中取出該JVM。這樣,出現(xiàn)問題的JVM就不會(huì)處理任何新的流量,可以最大限度地減少對(duì)客戶請(qǐng)求的影響。
可以使用GCeasy REST API實(shí)時(shí)監(jiān)控GC的微觀數(shù)據(jù),也可以使用gcviewer (https://github.com/chewiebug/GCViewer)離線分析GC日志文件。
-XX:+HeapDumpOnOutOfMemoryError, -XX:HeapDumpPath
OOM異常嚴(yán)重影響應(yīng)用的可用性/性能SLA等級(jí)。要診斷OOM異常或任何與內(nèi)存相關(guān)的問題,必須在應(yīng)用程序開始遇到OOM之前的某一時(shí)刻或幾分鐘捕獲heap dump(堆轉(zhuǎn)儲(chǔ)文件)。由于我們不知道OOM何時(shí)出來,所以很難手動(dòng)捕獲它。一般通過傳遞以下JVM參數(shù)來自動(dòng)捕獲heap dump:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={HEAP-DUMP-FILE-PATH}在-XX:HeapDumpPath中,我們?cè)O(shè)置一個(gè)堆轉(zhuǎn)儲(chǔ)文件地址。當(dāng)這兩個(gè)參數(shù)傳遞給JVM之后,當(dāng)拋出OOM的時(shí)候,heap dump會(huì)被自動(dòng)捕獲并存儲(chǔ)在指定文件路徑上。
一般可以使用jhat、EclipseMAT分析heap dump。
-Xss
每個(gè)應(yīng)用在運(yùn)行時(shí)都會(huì)產(chǎn)生大量線程,每個(gè)線程擁有自己的??臻g。在每個(gè)線程棧中包含了以下內(nèi)容:
- 當(dāng)前正在執(zhí)行的方法
- 原始數(shù)據(jù)類型
- 變量
- 對(duì)象指針
- 返回值
每一項(xiàng)都占用內(nèi)存。如果內(nèi)存占用超過一定限制,就會(huì)拋出StackOverflowError異常??梢允褂?Xss參數(shù)來調(diào)整線程棧的大小。例如:
-Xss256k如果設(shè)置-Xss過大,會(huì)造成內(nèi)存的阻塞和浪費(fèi)。例如,假設(shè)我們?cè)O(shè)置-Xss大小為2MB,但實(shí)際上,只需要256KB,就會(huì)造成非常大的內(nèi)存浪費(fèi),而不僅僅只是字面量上的1792KB。假設(shè)應(yīng)用一共有500個(gè)線程,當(dāng)-Xss設(shè)置為2MB,線程會(huì)總共占用1000MB內(nèi)存。而如果設(shè)置-Xss為256KB,實(shí)際總共只需要125MB內(nèi)存空間,總共節(jié)約了875MB內(nèi)存。所以,-Xss的設(shè)置會(huì)造成巨大的內(nèi)存消耗差異。
我們建議先將-Xss設(shè)置為一個(gè)較小的值,比如256KB,并使用該設(shè)置完成回歸、性能和AB測(cè)試。如果在這個(gè)過程中遇到了StackOverflowError,再逐步提高該值即可,否則使用一個(gè)較小的值。
-Dsun.net.client.defaultConnectTimeout 和 -Dsun.net.client.defaultReadTimeout
在一個(gè)應(yīng)用中,常常會(huì)涉及到使用各種協(xié)議(SOAP, REST, HTTP, HTTPS, JDBC, RMI等)和第三方應(yīng)用交互。有時(shí)候第三方應(yīng)用會(huì)響應(yīng)很慢,或者無響應(yīng)。
在這種情況下,如果沒有一個(gè)合理的超時(shí)時(shí)間設(shè)置,如果遠(yuǎn)端應(yīng)用沒法及時(shí)響應(yīng),則會(huì)造成我們的應(yīng)用線程/資源出現(xiàn)問題。遠(yuǎn)程應(yīng)用程序無響應(yīng)會(huì)影響我們程序的可用性。所以,設(shè)置合理的超時(shí)時(shí)間是非常必要的。
你可以通過設(shè)置這兩個(gè)非常強(qiáng)大的網(wǎng)絡(luò)參數(shù),在JVM層面上控制所有通過java.net.URLConnection建立的協(xié)議連接。
sun.net.client.defaultConnectTimeout:設(shè)置連接到主機(jī)的超時(shí)時(shí)間(毫秒)sun.net.client.defaultReadTimeout:與資源建立連接時(shí)從輸入流讀取數(shù)據(jù)的超時(shí)時(shí)間(毫秒)比如:
-Dsun.net.client.defaultConnectTimeout=2000-Dsun.net.client.defaultReadTimeout=2000如果設(shè)置為-1,則表示不超時(shí)。
原文鏈接:https://www.javacodegeeks.com/2020/03/7-jvm-arguments-of-highly-effective-applications.html
總結(jié)
以上是生活随笔為你收集整理的jvm 参数_6个提高性能的JVM参数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: loadrunner11 下载安装说明
- 下一篇: 项目管理基础:软件生命周期概念介绍