高效应用程序的7个JVM参数
在撰寫本文時(2020年3月),圍繞垃圾收集和內(nèi)存,您可以將600多個參數(shù)傳遞給JVM。 如果您包括其他方面,則JVM參數(shù)總數(shù)將很容易超過1000個。 😊。 任何人都無法消化和理解太多的論據(jù)。 在本文中,我們重點(diǎn)介紹了七個重要的JVM參數(shù),您可能會發(fā)現(xiàn)它很有用。
1. -Xmx和-XX:MaxMetaspaceSize
-Xmx可能是最重要的JVM參數(shù)。 -Xmx定義要分配給應(yīng)用程序的最大堆大小。 (要了解JVM中不同的內(nèi)存區(qū)域,您可以觀看此短片 )。 您可以這樣定義應(yīng)用程序的堆大小:
-Xmx2g堆大小在確定您的
一個。 應(yīng)用性能
b。 Bill,您將從云提供商(AWS,Azure等)獲得收益
這帶來了一個問題,我的應(yīng)用程序正確的堆大小是多少? 我應(yīng)該為應(yīng)用程序分配大堆大小還是小堆大小? 答案是:“取決于”。 在本文中 ,我們分享了我們的想法,無論您需要使用大堆還是小堆。
You might also consider reading this article: advantages of setting -Xms and -Xmx to same value.元空間是將存儲JVM的元數(shù)據(jù)定義(例如類定義,方法定義)的區(qū)域。 默認(rèn)情況下,可用于存儲此元數(shù)據(jù)信息的內(nèi)存量是無限的(即受您的容器或計(jì)算機(jī)的RAM大小的限制)。 您需要使用-XX:MaxMetaspaceSize參數(shù)來指定可用于存儲元數(shù)據(jù)信息的內(nèi)存量的上限。
-XX:MaxMetaspaceSize=256m2. GC算法
截止到2020年3月,OpenJDK中有7種不同的GC算法:
一個。 串行GC
b。 平行氣相色譜
C。 并發(fā)標(biāo)記和掃描GC
d。 G1 GC
e。 雪蘭多GC
F。 Z氣相色譜
G。 Epsilon GC
如果您未明確指定GC算法,那么JVM將選擇默認(rèn)算法。 在Java 8之前,并行GC是默認(rèn)的GC算法。 從Java 9開始,G1 GC是默認(rèn)的GC算法。
GC算法的選擇對于確定應(yīng)用程序的性能起著至關(guān)重要的作用。 基于我們的研究,我們正在使用Z GC算法觀察到出色的性能結(jié)果。 如果使用JVM 11+,則可以考慮使用Z GC算法(即-XX:+ UseZGC)。 有關(guān)Z GC算法的更多詳細(xì)信息,請參見此處 。
下表總結(jié)了激活每種垃圾收集算法所需傳遞的JVM參數(shù)。
| GC算法 | JVM參數(shù) |
| 串行GC | -XX:+ UseSerialGC |
| 平行氣相色譜 | -XX:+ UseParallelGC |
| 并發(fā)市場和掃描(CMS)GC | -XX:+ UseConcMarkSweepGC |
| G1 GC | -XX:+ UseG1GC |
| 雪蘭多GC | -XX:+使用ShenandoahGC |
| Z氣相色譜 | -XX:+使用ZGC |
| Epsilon GC | -XX:+ UseEpsilonGC |
3.啟用GC日志記錄
垃圾收集日志包含有關(guān)垃圾收集事件,回收的內(nèi)存,暫停時間段等信息,您可以通過傳遞以下JVM參數(shù)來啟用垃圾收集日志:
從JDK 1到JDK 8:
GC算法從JDK 9及更高版本開始:
GC算法例:
GC算法通常,GC日志用于調(diào)整垃圾回收性能。 但是,GC日志包含重要的微觀指標(biāo)。 這些指標(biāo)可用于預(yù)測應(yīng)用程序的可用性和性能特征。 在本文中,我們將重點(diǎn)介紹一種這樣的千分尺:“ GC吞吐量 ”(要了解其他可用千分尺的更多信息,您可以參考本文 )。 GC吞吐量是您的應(yīng)用程序在處理客戶交易中花費(fèi)的時間與它在處理GC活動中花費(fèi)的時間之比。 假設(shè)您的應(yīng)用程序的GC吞吐量為98%,則意味著應(yīng)用程序?qū)⑵?8%的時間用于處理客戶活動,而其余2%則用于GC活動。
現(xiàn)在,讓我們看一個健康的JVM的堆使用情況圖:
圖:健康JVM的堆使用情況圖(由https://gceasy.io生成)
您會看到一個完美的鋸齒圖案。 您會注意到,當(dāng)運(yùn)行Full GC(紅色三角形)時,內(nèi)存利用率會一直下降到最低。
現(xiàn)在,讓我們看一下有問題的JVM的堆使用情況圖:
圖:Sick JVM的堆使用情況圖(由https://gceasy.io生成)
您可以注意到,在圖形的右端,即使GC重復(fù)運(yùn)行,內(nèi)存利用率也沒有下降。 這是該應(yīng)用程序正遭受某種內(nèi)存問題的經(jīng)典征兆。
如果您仔細(xì)觀察一下該圖,您會發(fā)現(xiàn)重復(fù)的完整GC開始在上午8點(diǎn)左右開始。 但是,該應(yīng)用程序僅在上午8:45左右開始獲取OutOfMemoryError。 到上午8點(diǎn),該應(yīng)用程序的GC吞吐量約為99%。 但是,在早上8點(diǎn)之后,GC吞吐量開始下降到60%。 因?yàn)楫?dāng)重復(fù)的GC運(yùn)行時,該應(yīng)用程序?qū)⒉粫幚砣魏慰蛻艚灰?#xff0c;而只會進(jìn)行GC活動。 作為一項(xiàng)主動措施,如果您發(fā)現(xiàn)GC吞吐量開始下降,則可以從負(fù)載平衡器池中取出JVM。 這樣,運(yùn)行狀況不佳的JVM將不會處理任何新的流量。 它將最大程度地減少對客戶的影響。
圖:重復(fù)的完整GC發(fā)生在OutOfMemoryError之前
您可以使用GCeasy REST API實(shí)時監(jiān)視與GC相關(guān)的微米。
4. -XX:+ HeapDumpOnOutOfMemoryError,-XX:HeapDumpPath
OutOfMemoryError是一個嚴(yán)重的問題,它將影響您的應(yīng)用程序的可用性/性能SLA。 為了診斷OutOfMemoryError或任何與內(nèi)存相關(guān)的問題,必須在應(yīng)用程序開始遇到OutOfMemoryError的那一刻或一瞬間捕獲堆轉(zhuǎn)儲。 由于我們不知道何時會拋出OutOfMemoryError,因此很難在拋出時左右的正確時間手動捕獲堆轉(zhuǎn)儲。 但是,可以通過傳遞以下JVM參數(shù)來自動化捕獲堆轉(zhuǎn)儲:
-XX:+ HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath = {HEAP-DUMP-FILE-PATH}
在“ -XX:HeapDumpPath”中,您需要指定堆轉(zhuǎn)儲所在的文件路徑。 傳遞這兩個JVM參數(shù)時,將在拋出OutOfMemoryError時自動捕獲堆轉(zhuǎn)儲并將其寫入定義的文件路徑。 例:
GC算法一旦捕獲了堆轉(zhuǎn)儲,就可以使用HeapHero和EclipseMAT之類的工具來分析堆轉(zhuǎn)儲。
有關(guān)OutOfMemoryError JVM參數(shù)的更多詳細(xì)信息,可以在本文中找到。
5. -Xss
每個應(yīng)用程序?qū)⒕哂袛?shù)十,數(shù)百,數(shù)千個線程。 每個線程都有自己的堆棧。 在每個線程的堆棧中,存儲以下信息:
一個。 當(dāng)前執(zhí)行的方法/功能
b。 原始數(shù)據(jù)類型
C。 變數(shù)
d。 對象指針
e。 返回值。
他們每個人都消耗內(nèi)存。 如果它們的使用量超出某個限制,則拋出StackOverflowError。 有關(guān)StackOverflowError及其解決方案的更多詳細(xì)信息,請參見本文 。 但是,可以通過傳遞-Xss參數(shù)來增加線程的堆棧大小限制。 例:
GC算法如果將此-Xss值設(shè)置為一個很大的數(shù)字,則內(nèi)存將被阻塞并浪費(fèi)。 假設(shè)您將-Xss值指定為2mb,而它只需要256kb,那么您將浪費(fèi)大量的內(nèi)存,而不僅僅是1792kb(即2mb – 256kb)。 你想知道為什么嗎?
假設(shè)您的應(yīng)用程序有500個線程,那么-Xss值為2mb,您的線程將消耗1000mb的內(nèi)存(即500個線程x 2mb /線程)。 另一方面,如果您僅將-Xss分配為256kb,那么您的線程將僅消耗125mb的內(nèi)存(即500個線程x 256kb /線程)。 每個JVM將節(jié)省875mb(即1000mb – 125mb)內(nèi)存。 是的,它將產(chǎn)生巨大的變化。
注意:線程是在堆(即-Xmx)外部創(chuàng)建的,因此這1000mb將是您已經(jīng)分配的-Xmx值的補(bǔ)充。 要了解為什么在堆外部創(chuàng)建線程,您可以觀看此簡短視頻片段 。
我們的建議是從一個低值(例如256kb)開始。 使用此設(shè)置運(yùn)行徹底的回歸,性能和AB測試。 僅當(dāng)您遇到StackOverflowError時才增加該值,否則請考慮堅(jiān)持較低的值。
6. -Dsun.net.client.defaultConnectTimeout和-Dsun.net.client.defaultReadTimeout
現(xiàn)代應(yīng)用程序使用多種協(xié)議(即SOAP,REST,HTTP,HTTPS,JDBC,RMI…)與遠(yuǎn)程應(yīng)用程序連接。 有時遠(yuǎn)程應(yīng)用程序可能需要很長時間才能做出響應(yīng)。 有時它可能根本不響應(yīng)。
如果沒有正確的超時設(shè)置,并且遠(yuǎn)程應(yīng)用程序的響應(yīng)速度不夠快,則應(yīng)用程序線程/資源將被卡住。 遠(yuǎn)程應(yīng)用程序無響應(yīng)可能會影響您的應(yīng)用程序的可用性。 它可以使您的應(yīng)用程序停止磨削。 為了保護(hù)您的應(yīng)用程序的高可用性,應(yīng)配置適當(dāng)?shù)某瑫r設(shè)置。
您可以在JVM級別傳遞這兩個強(qiáng)大的超時網(wǎng)絡(luò)屬性,這些屬性可以全局適用于所有使用java.net.URLConnection的協(xié)議處理程序:
例如,如果要將這些屬性設(shè)置為2秒:
GC算法注意,默認(rèn)情況下,這兩個屬性的值為-1,這表示未設(shè)置超時。 有關(guān)這些屬性的更多詳細(xì)信息,請參見本文 。
7. -Duser.timeZone
您的應(yīng)用程序可能在某個時間/日期附近具有敏感的業(yè)務(wù)需求。 例如,如果您正在構(gòu)建交易應(yīng)用程序,則不能在上午9:30之前進(jìn)行交易。 為了實(shí)現(xiàn)那些與時間/日期相關(guān)的業(yè)務(wù)需求,您可以使用java.util.Date,java.util.Calendar對象。 默認(rèn)情況下,這些對象從底層操作系統(tǒng)中獲取時區(qū)信息。 這將成為一個問題; 如果您的應(yīng)用程序在分布式環(huán)境中運(yùn)行。 查看以下方案:
一個。 如果您的應(yīng)用程序跨多個數(shù)據(jù)中心(例如,舊金山,芝加哥,新加坡)運(yùn)行,則每個數(shù)據(jù)中心中的JVM最終將具有不同的時區(qū)。 因此,每個數(shù)據(jù)中心中的JVM將表現(xiàn)出不同的行為。 這將導(dǎo)致結(jié)果不一致。
b。 如果要在云環(huán)境中部署應(yīng)用程序,則可能會在您不知情的情況下將應(yīng)用程序移動到其他數(shù)據(jù)中心。 同樣在這種情況下,您的應(yīng)用程序最終將產(chǎn)生不同的結(jié)果。
C。 您自己的運(yùn)營團(tuán)隊(duì)還可以更改時區(qū),而無需掌握開發(fā)團(tuán)隊(duì)的知識。 它還會歪曲結(jié)果。
為避免這些麻煩,強(qiáng)烈建議使用-Duser.timezone系統(tǒng)屬性在JVM上設(shè)置時區(qū)。 例如,如果您想為應(yīng)用程序設(shè)置EDT時區(qū),則將執(zhí)行以下操作:
GC算法結(jié)論
在本文中,我們試圖總結(jié)一些重要的JVM參數(shù)及其積極影響。 希望對您有所幫助。
翻譯自: https://www.javacodegeeks.com/2020/03/7-jvm-arguments-of-highly-effective-applications.html
總結(jié)
以上是生活随笔為你收集整理的高效应用程序的7个JVM参数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 进浙备案登记(离浙备案)
- 下一篇: junit:junit_简而言之,JUn