新聞中心
對(duì)于 Java 開發(fā)人員來(lái)說(shuō),進(jìn)行程序的性能優(yōu)化是很有挑戰(zhàn)的工作,也是很有意義的一件事。本篇主要根據(jù) JVM 內(nèi)存模型和垃圾回收的詳細(xì)講解,可以更好的理解JVM的調(diào)優(yōu)的根本原理。

10年積累的成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有珠海免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
JVM內(nèi)存模型
JVM 架構(gòu)
- 類加載器(Classloader):類加載器是JVM的一個(gè)子系統(tǒng),用于加載類文件。每當(dāng)我們運(yùn)行java程序時(shí),它首先由類加載器加載。
- 類(方法)區(qū)(Class(Method) Area):類(方法)區(qū)存儲(chǔ)每個(gè)類的結(jié)構(gòu),例如運(yùn)行時(shí)常量池、字段和方法數(shù)據(jù)、方法的代碼。
- 堆(Heap):是分配對(duì)象的運(yùn)行時(shí)數(shù)據(jù)區(qū)域。
- 堆棧(Stack):Java 堆棧存儲(chǔ)幀。它保存局部變量和部分結(jié)果,并在方法調(diào)用和返回中發(fā)揮作用。每個(gè)線程都有一個(gè)私有的 JVM 堆棧,與該線程同時(shí)創(chuàng)建。每次調(diào)用方法時(shí)都會(huì)創(chuàng)建一個(gè)新框架。當(dāng)其方法調(diào)用完成時(shí),框架將被銷毀。
- 程序計(jì)數(shù)器寄存器(PC):PC(程序計(jì)數(shù)器)寄存器包含當(dāng)前正在執(zhí)行的Java虛擬機(jī)指令的地址。
- 本機(jī)方法堆棧(Native Method Stack):它包含應(yīng)用程序中使用的所有本機(jī)方法。
- 執(zhí)行引擎(Execution Engine):它包含:一個(gè)虛擬處理器;解釋器:讀取字節(jié)碼流然后執(zhí)行指令。
- Just-In-Time(JIT)編譯器:它用于提高性能。JIT 同時(shí)編譯具有相似功能的字節(jié)碼部分,從而減少編譯所需的時(shí)間。這里,術(shù)語(yǔ)“編譯器”是指從Java虛擬機(jī)(JVM)的指令集到特定CPU的指令集的翻譯器。
- Java 本機(jī)接口:Java 本機(jī)接口 (JNI) 是一個(gè)框架,提供與用其他語(yǔ)言(如 C、C++、匯編等)編寫的另一個(gè)應(yīng)用程序進(jìn)行通信的接口。Java 使用 JNI 框架將輸出發(fā)送到控制臺(tái)或與操作系統(tǒng)交互。
應(yīng)該已經(jīng)使用了一些像這樣的 JVM 配置
JAVA_OPTS=”-server -Xms2560m -Xmx2560m -XX:NewSize=1536m -XX:MaxNewSize=1536m -XX:MetaspaceSize=768m -XX:MaxMetaspaceSize=768m -XX:InitialCodeCacheSize=64m -XX:ReservedCodeCacheSize=96m -XX:MaxTenuringThreshold=5″- -server - 啟用“ServerHotspotVM”;該參數(shù)在 64 位 JVM 中默認(rèn)使用。
- -Xms - 堆的初始空間。
- -Xmx - 堆的最大空間。
- -XX:NewSize - 初始新空間。將新大小設(shè)置為總堆的一半通常比使用較小的新大小提供更好的性能。
- -XX:MaxNewSize - 最大新空間。
- -XX:MetaspaceSize - 靜態(tài)內(nèi)容的初始空間。
- -XX:MaxMetaspaceSize - 靜態(tài)內(nèi)容的最大空間。
- -XX:InitialCodeCacheSize - JIT 編譯代碼的初始空間。代碼緩存太?。J(rèn)為 48m)會(huì)降低性能,因?yàn)?JIT 無(wú)法優(yōu)化高頻方法。
- -XX:ReservedCodeCacheSize - JIT 編譯代碼的最大空間。
- -XX:MaxTenuringThreshold - 在升級(jí)到老年代空間之前,將幸存者保留在幸存者空間中最多 15 次垃圾回收。
那么 JVM 是如何駐留在內(nèi)存上的?JVM 消耗主機(jī)操作系統(tǒng)內(nèi)存上的可用空間。
然而,在 JVM 內(nèi)部,存在獨(dú)立的內(nèi)存空間(堆、非堆、緩存),以存儲(chǔ)運(yùn)行時(shí)數(shù)據(jù)和編譯后的代碼。
堆內(nèi)存
- 堆分為兩部分:Young Generation 和 Old Generation
- JVM 啟動(dòng)時(shí)分配堆(初始大?。?Xms)
- 應(yīng)用程序運(yùn)行時(shí)堆大小增加/減少
- 堆的最大空間:-Xmx
以下是有關(guān)服務(wù)器應(yīng)用程序堆大小的一般準(zhǔn)則:
- 除非遇到暫停問(wèn)題,否則請(qǐng)嘗試為虛擬機(jī)授予盡可能多的內(nèi)存。默認(rèn)大小通常太小。
- 將-Xms和-Xmx設(shè)置為相同的值可以消除虛擬機(jī)中最重要的大小調(diào)整決策,從而提高可預(yù)測(cè)性。但是如果設(shè)置相同大小出了錯(cuò)誤,虛擬機(jī)將無(wú)法進(jìn)行補(bǔ)償。
- 一般來(lái)說(shuō),隨著處理器數(shù)量的增加,內(nèi)存也會(huì)隨之增加,因?yàn)榉峙淇梢圆⑿羞M(jìn)行。
年輕代(Young Generation)
- 這是為包含新分配的對(duì)象而保留的
- Young Gen 包括三個(gè)部分——Eden Memory 和兩個(gè) Survivor Memory 空間(S0、S1)
- 大多數(shù)新創(chuàng)建的對(duì)象都會(huì)進(jìn)入Eden space。
- 當(dāng) Eden 空間充滿對(duì)象時(shí),將執(zhí)行 Minor GC(又名 Young Collection),并將所有幸存者對(duì)象移動(dòng)到幸存者空間之一。
- Minor GC 還會(huì)檢查幸存者對(duì)象并將它們移動(dòng)到其他幸存者空間。所以在某一時(shí)刻,幸存者的一個(gè)空間總是空著的。
- 經(jīng)過(guò)多次GC后幸存的對(duì)象會(huì)被移至Old代內(nèi)存空間。通常,這是通過(guò)在年輕代對(duì)象有資格晉升到老年代之前設(shè)置年齡閾值(-XX:MaxTenuringThreshold)來(lái)完成的。
老年代(Old Generation)
- 這是為包含在多輪 Minor GC 后仍能存活的長(zhǎng)壽命對(duì)象而保留的
- 當(dāng) Old Gen 空間滿時(shí),將執(zhí)行 Major GC(又名 Old Collection)(通常需要更長(zhǎng)的時(shí)間)
非堆內(nèi)存
- 這包括永久生成(自 Java 8 起被 Metaspace 取代)
- Perm Gen 存儲(chǔ)每個(gè)類的結(jié)構(gòu),例如運(yùn)行時(shí)常量池、字段和方法數(shù)據(jù)、方法和構(gòu)造函數(shù)的代碼以及內(nèi)部字符串
- 可以使用 -XX:PermSize 和 -XX:MaxPermSize 更改其大小
高速緩存存儲(chǔ)器
- 這包括代碼緩存
- 存儲(chǔ)JIT編譯器生成的編譯代碼(即本機(jī)代碼)、JVM內(nèi)部結(jié)構(gòu)、加載的分析器代理代碼和數(shù)據(jù)等。
- 當(dāng)代碼緩存超過(guò)閾值時(shí),它會(huì)被刷新(GC 不會(huì)重新定位對(duì)象)。
什么是GC?
Java 通過(guò)一個(gè)稱為垃圾收集器的程序提供自動(dòng)內(nèi)存管理。
“移除不再使用的對(duì)象?!?/p>
上面的一切都是在堆中完成的,堆是運(yùn)行時(shí)動(dòng)態(tài)內(nèi)存分配的空間,用于包含所有 java 對(duì)象。除了堆之外,還有堆棧,其中包含支持線程執(zhí)行的局部變量和函數(shù)調(diào)用。
Java 垃圾收集的實(shí)際工作原理
許多人認(rèn)為垃圾收集會(huì)收集并丟棄死對(duì)象。事實(shí)上,Java 垃圾收集的作用恰恰相反!活動(dòng)對(duì)象被跟蹤,其他所有對(duì)象都被指定為垃圾。這種根本性的誤解可能會(huì)導(dǎo)致許多性能問(wèn)題。
讓我們從堆開始,它是用于動(dòng)態(tài)分配的內(nèi)存區(qū)域。在大多數(shù)配置中,操作系統(tǒng)會(huì)提前分配堆,以便在程序運(yùn)行時(shí)由 JVM 管理。這有幾個(gè)重要的影響:
- 對(duì)象創(chuàng)建速度更快,因?yàn)椴恍枰總€(gè)對(duì)象都與操作系統(tǒng)進(jìn)行全局同步。分配只是聲明內(nèi)存數(shù)組的某些部分并將偏移指針向前移動(dòng)(參見(jiàn)圖 2.1)。下一個(gè)分配從此偏移量開始,并聲明數(shù)組的下一部分。
- 當(dāng)不再使用某個(gè)對(duì)象時(shí),垃圾收集器會(huì)回收底層內(nèi)存并將其重新用于將來(lái)的對(duì)象分配。這意味著沒(méi)有顯式刪除,也沒(méi)有內(nèi)存返回給操作系統(tǒng)。
新對(duì)象簡(jiǎn)單地分配在已用堆的末尾
一旦某個(gè)對(duì)象不再被引用并且因此應(yīng)用程序代碼無(wú)法訪問(wèn)該對(duì)象,垃圾收集器就會(huì)將其刪除并回收未使用的內(nèi)存。
垃圾收集根——所有對(duì)象樹的來(lái)源
每個(gè)對(duì)象樹必須有一個(gè)或多個(gè)根對(duì)象。只要應(yīng)用程序可以到達(dá)這些根,那么整棵樹都是可以到達(dá)的。但是這些根對(duì)象什么時(shí)候被認(rèn)為是可達(dá)的呢?稱為垃圾收集根,它是特殊對(duì)象始終是可訪問(wèn)的,任何在其根處具有垃圾收集根的對(duì)象也是如此。
Java中有四種GC root:
- 局部變量通過(guò)線程的堆棧保持活動(dòng)狀態(tài)。這不是真實(shí)的對(duì)象虛擬引用,因此不可見(jiàn)。無(wú)論如何,局部變量都是 GC 根。
- 活動(dòng)的 Java 線程始終被視為活動(dòng)對(duì)象,因此是 GC 根。這對(duì)于線程局部變量尤其重要。
- 靜態(tài)變量由它們的類引用。這一事實(shí)使它們成為事實(shí)上的 GC 根。類本身可以被垃圾收集,這將刪除所有引用的靜態(tài)變量。
- JNI 引用是本機(jī)代碼作為 JNI 調(diào)用的一部分創(chuàng)建的 Java 對(duì)象。這樣創(chuàng)建的對(duì)象會(huì)被特殊對(duì)待,因?yàn)?JVM 不知道它是否被本機(jī)代碼引用。
GC 根是 JVM 本身引用的對(duì)象,因此可以防止其他所有對(duì)象被垃圾收集。
因此,一個(gè)簡(jiǎn)單的 Java 應(yīng)用程序具有以下 GC 根:
- main方法中的局部變量
- 主線程
- 主類的靜態(tài)變量
標(biāo)記并清除垃圾
標(biāo)記可達(dá)對(duì)象
為了確定哪些對(duì)象不再使用,JVM 間歇性地運(yùn)行所謂的“標(biāo)記和清除”算法。正如所直覺(jué)的,這是一個(gè)簡(jiǎn)單的兩步過(guò)程:
- 該算法從 GC 根開始遍歷所有對(duì)象引用,并將找到的每個(gè)對(duì)象標(biāo)記為活動(dòng)對(duì)象。
- 所有未被標(biāo)記對(duì)象占用的堆內(nèi)存都會(huì)被回收。它只是被簡(jiǎn)單地標(biāo)記為空閑,基本上清除了未使用的對(duì)象。
活動(dòng)對(duì)象在上圖中表示為藍(lán)色。當(dāng)標(biāo)記階段結(jié)束時(shí),每個(gè)活動(dòng)對(duì)象都被標(biāo)記。因此,所有其他對(duì)象(上圖中的灰色數(shù)據(jù)結(jié)構(gòu))都無(wú)法從 GC 根訪問(wèn),這意味著應(yīng)用程序無(wú)法再使用無(wú)法訪問(wèn)的對(duì)象。此類對(duì)象被視為垃圾,GC 應(yīng)在以下階段中刪除它們。
標(biāo)記階段需要注意以下重要方面:
- 需要停止應(yīng)用程序線程才能進(jìn)行標(biāo)記,因?yàn)槿绻麍D表一直在不斷變化,就無(wú)法真正遍歷圖表。當(dāng)應(yīng)用程序線程暫時(shí)停止以便 JVM 可以進(jìn)行內(nèi)務(wù)活動(dòng)時(shí),這種情況稱為安全點(diǎn),導(dǎo)致 Stop The World 暫停。安全點(diǎn)可以因不同的原因而被觸發(fā),但垃圾收集是迄今為止引入安全點(diǎn)的最常見(jiàn)原因。
- 此暫停的持續(xù)時(shí)間既不取決于堆中對(duì)象的總數(shù),也不取決于堆的大小,而是取決于活動(dòng)對(duì)象的數(shù)量。因此增加堆的大小并不會(huì)直接影響標(biāo)記階段的持續(xù)時(shí)間。
- 當(dāng)標(biāo)記階段完成后,GC就可以進(jìn)行下一步并開始刪除不可達(dá)的對(duì)象。
刪除未使用的對(duì)象
對(duì)于不同的 GC 算法,未使用對(duì)象的刪除略有不同,但所有此類 GC 算法都可以分為三步:清除(sweeping)、壓縮(compacting)和復(fù)制(copying)。
Sweep
標(biāo)記和清除算法在概念上使用最簡(jiǎn)單的垃圾處理方法,即忽略此類對(duì)象。這意味著在標(biāo)記階段完成后,未訪問(wèn)對(duì)象占用的所有空間都被視為空閑,因此可以重用以分配新對(duì)象。
該方法需要使用所謂的空閑列表記錄每個(gè)空閑區(qū)域及其大小??臻e列表的管理增加了對(duì)象分配的開銷。這種方法還有另一個(gè)弱點(diǎn)——可能存在大量空閑區(qū)域,但如果沒(méi)有一個(gè)區(qū)域足夠大來(lái)容納分配,分配仍然會(huì)失?。ㄔ?Java 中會(huì)出現(xiàn) OutOfMemoryError 錯(cuò)誤)。
它通常被稱為標(biāo)記-清除算法。
Compact
Mark-Sweep-Compact算法通過(guò)將所有標(biāo)記的對(duì)象 (即活動(dòng)的對(duì)象)移動(dòng)到內(nèi)存區(qū)域的開頭來(lái)解決Mark-and-Sweep算法的缺點(diǎn)。這種方法的缺點(diǎn)是增加了GC暫停時(shí)間,因?yàn)槲覀冃枰獙⑺袑?duì)象復(fù)制到一個(gè)新位置,并更新對(duì)這些對(duì)象的所有引用。Markand Sweep的好處也是顯而易見(jiàn)的--在這樣一個(gè)壓縮操作之后,通過(guò)指針碰撞,新對(duì)象的分配再次變得非常便宜。使用這種方法,空閑空間的位置總是已知的,也不會(huì)觸發(fā)碎片問(wèn)題。
它通常被稱為標(biāo)記-壓縮算法。
Copy
標(biāo)記和復(fù)制算法非常類似于標(biāo)記和壓縮,因?yàn)樗鼈円仓匦露ㄎ凰谢顒?dòng)對(duì)象。重要的區(qū)別在于,對(duì)象搬遷的目標(biāo)是不同的記憶區(qū)域,作為幸存對(duì)象的新家。標(biāo)記和復(fù)制方法具有一些優(yōu)點(diǎn),因?yàn)閺?fù)制可以與標(biāo)記在同一階段同時(shí)發(fā)生。缺點(diǎn)是需要多一個(gè)內(nèi)存區(qū)域,該內(nèi)存區(qū)域應(yīng)該足夠大以容納幸存的對(duì)象。
它通常被稱為標(biāo)記復(fù)制算法。
停止世界 (STW)
所有垃圾收集都是“Stop the World”事件。這意味著所有應(yīng)用程序線程都將停止,直到操作完成。垃圾收集始終是“Stop the World”事件。
老年代用于存儲(chǔ)長(zhǎng)期存活的對(duì)象。通常,為年輕代對(duì)象設(shè)置一個(gè)閾值,當(dāng)達(dá)到該年齡時(shí),該對(duì)象將被移動(dòng)到老年代。最終需要收集老年代。此事件稱為主垃圾收集。
主垃圾收集也是 Stop the World 事件。通常,主垃圾收集要慢得多,因?yàn)樗婕八谢顒?dòng)對(duì)象。因此,對(duì)于響應(yīng)式應(yīng)用程序,應(yīng)最大程度地減少主要垃圾收集。另請(qǐng)注意,主要垃圾收集的 Stop the World 事件的長(zhǎng)度受到用于老年代空間的垃圾收集器類型的影響。
GC 可視化過(guò)程
當(dāng)應(yīng)用程序啟動(dòng)并在 Eden 空間上分配內(nèi)存時(shí)。藍(lán)色是活動(dòng)對(duì)象,灰色是死對(duì)象(無(wú)法到達(dá))。當(dāng)給定空間已滿時(shí),應(yīng)用程序嘗試創(chuàng)建另一個(gè)對(duì)象,并且 JVM 嘗試在 Eden 上分配某些內(nèi)容,但分配失敗。這實(shí)際上會(huì)導(dǎo)致輕微GC。
第一次minor GC后,所有存活對(duì)象將被移動(dòng)到Survivor 1,年齡為1,死亡對(duì)象將被刪除。
應(yīng)用程序正在運(yùn)行,新對(duì)象再次在 Eden 空間中分配。有些對(duì)象在 Eden 空間和 Survivor 1 上都變得無(wú)法訪問(wèn)
在第二次 Minor GC 之后,所有存活對(duì)象將被移動(dòng)到 Survivor 2(來(lái)自年齡為 1 的 Eden 和年齡為 2 的 Survivor 1),并且死亡對(duì)象將被刪除。
應(yīng)用程序仍在運(yùn)行,新對(duì)象在 Eden 空間上分配,過(guò)了一會(huì)兒,一些對(duì)象從 Eden 和 Survivor 2 都無(wú)法訪問(wèn)
在第三次minor GC之后,隨著年齡的增加,所有存活對(duì)象將從Eden和Survivor 2移動(dòng)到Survivor 1,并且死亡對(duì)象將被刪除。
在Survivor中存活時(shí)間較長(zhǎng)的對(duì)象,如果年齡大于-XX:MaxTenuringThreshold,將會(huì)被提升到老年代(Tuner)
我們可以使用 VisualVM 的插件 VisualGC 附加到已檢測(cè)的 HotSpot JVM,收集并以圖形方式顯示垃圾收集、類加載器和 HotSpot 編譯器性能數(shù)據(jù)。
性能基礎(chǔ)知識(shí)
通常,在調(diào)整 Java 應(yīng)用程序時(shí),重點(diǎn)是兩個(gè)主要目標(biāo)之一:響應(yīng)速度和吞吐量。
響應(yīng)速度
響應(yīng)能力是指應(yīng)用程序或系統(tǒng)響應(yīng)所請(qǐng)求的數(shù)據(jù)的速度。示例包括:
- 桌面 UI 響應(yīng)事件的速度有多快
- 網(wǎng)站返回頁(yè)面的速度有多快
- 返回?cái)?shù)據(jù)庫(kù)查詢的速度有多快
對(duì)于注重響應(yīng)能力的應(yīng)用程序來(lái)說(shuō),較長(zhǎng)的暫停時(shí)間是不可接受的。重點(diǎn)是在短時(shí)間內(nèi)做出響應(yīng)。
吞吐量
吞吐量側(cè)重于在特定時(shí)間段內(nèi)最大化應(yīng)用程序的工作量。如何測(cè)量吞吐量的示例包括:
- 在給定時(shí)間內(nèi)完成的交易數(shù)量。
- 批處理程序在一小時(shí)內(nèi)可以完成的作業(yè)數(shù)。
- 一小時(shí)內(nèi)可以完成的數(shù)據(jù)庫(kù)查詢數(shù)量。
對(duì)于注重吞吐量的應(yīng)用程序來(lái)說(shuō),較長(zhǎng)的暫停時(shí)間是可以接受的。由于高吞吐量應(yīng)用程序關(guān)注較長(zhǎng)時(shí)間段的基準(zhǔn),因此不考慮快速響應(yīng)時(shí)間。
GC 有哪些類型?
并發(fā)標(biāo)記清除 (CMS) 垃圾收集
CMS垃圾收集本質(zhì)上是升級(jí)的標(biāo)記和清除算法。它使用多個(gè)線程掃描堆內(nèi)存。它經(jīng)過(guò)修改以利用更快的系統(tǒng)并增強(qiáng)了性能。
它嘗試通過(guò)與應(yīng)用程序線程同時(shí)執(zhí)行大部分垃圾收集工作來(lái)最大程度地減少由于垃圾收集而導(dǎo)致的暫停。它在年輕代中使用并行的 stop-the-world 標(biāo)記復(fù)制算法,在老年代中使用大多數(shù)并發(fā)的標(biāo)記清除算法。
要使用 CMS GC,請(qǐng)使用以下 JVM 參數(shù):
-XX:+UseConcMarkSweepGC串行垃圾收集
該算法對(duì)年輕代使用標(biāo)記-復(fù)制,對(duì)老生代使用標(biāo)記-清除-壓縮。它在單線程上工作。執(zhí)行時(shí),它會(huì)凍結(jié)所有其他線程,直到垃圾收集操作結(jié)束。
由于串行垃圾收集的線程凍結(jié)性質(zhì),它僅適用于非常小的程序垃圾收集。
要使用串行 GC,請(qǐng)使用以下 JVM 參數(shù):
-XX:+UseSerialGC并行垃圾收集
與串行GC類似,它在年輕代中使用標(biāo)記復(fù)制,在老年代中使用標(biāo)記清除緊湊。多個(gè)并發(fā)線程用于標(biāo)記和復(fù)制/壓縮階段??梢允褂?-XX:ParallelGCThreads=N 選項(xiàng)配置線程數(shù)。
如果主要的目標(biāo)是通過(guò)有效利用現(xiàn)有系統(tǒng)資源來(lái)提高吞吐量,則并行垃圾收集器適用于多核計(jì)算機(jī)。使用這種方法,可以大大縮短 GC 循環(huán)時(shí)間。
要使用并行 GC,請(qǐng)使用以下 JVM 參數(shù):
-XX:+UseParallelGCG1垃圾收集
G1(垃圾優(yōu)先)垃圾收集器在 Java 7 中可用,旨在作為 CMS 收集器的長(zhǎng)期替代品。G1 收集器是一個(gè)并行、并發(fā)、增量壓縮的低暫停垃圾收集器。
這種方法涉及將內(nèi)存堆分割成多個(gè)小區(qū)域(通常為 2048 個(gè))。每個(gè)區(qū)域都被標(biāo)記為年輕代(進(jìn)一步分為eden regions或survivor regions)或老年代。這使得 GC 可以避免一次收集整個(gè)堆,而是逐步解決問(wèn)題。這意味著一次僅考慮區(qū)域的子集。
G1 持續(xù)跟蹤每個(gè)區(qū)域包含的實(shí)時(shí)數(shù)據(jù)量。該信息用于確定包含最多垃圾的區(qū)域;所以首先收集它們。這就是為什么它被稱為垃圾優(yōu)先收集。
不幸的是,就像其他算法一樣,壓縮操作是使用 Stop the World 方法進(jìn)行的。但根據(jù)其設(shè)計(jì)目標(biāo),可以為其設(shè)置特定的性能目標(biāo)。還可以配置暫停持續(xù)時(shí)間,例如在任何給定的秒內(nèi)不超過(guò) 10 毫秒。垃圾優(yōu)先 GC 將盡最大努力以高概率實(shí)現(xiàn)這一目標(biāo)(但不確定,由于操作系統(tǒng)級(jí)別的線程管理)。
如果你想在 Java 7 或 Java 8 機(jī)器上使用,請(qǐng)使用 JVM 參數(shù),如下所示:
-XX:+UseSerialGCG1 優(yōu)化選項(xiàng)
- -XX:G1HeapReginotallow=16m 堆區(qū)域的大小。該值是 2 的冪,范圍從 1MB 到 32MB。目標(biāo)是根據(jù)最小 Java 堆大小擁有大約 2048 個(gè)區(qū)域。
- -XX:MaxGCPauseMillis=200 設(shè)置所需最大暫停時(shí)間的目標(biāo)值。默認(rèn)值為 200 毫秒。指定的值不適合堆大小。
- -XX:G1ReservePercent=5 這確定堆中的最小保留量。
- -XX:G1Cnotallow=75 這是確信度百分比。
- -XX:GCPauseIntervalMillis=200 這是每個(gè) MMU 的暫停間隔時(shí)間片(以毫秒為單位)。
建議
G1配置
-XX:+UseG1GC \
-XX:+UseStringDeduplication \
-XX:+ParallelRefProcEnabled \
-XX:+AlwaysPreTouch \
-XX:+DisableExplicitGC \
-XX:ParallelGCThreads=8 \
-XX:GCTimeRatio=9 \
-XX:MaxGCPauseMillis=25 \
-XX:MaxGCMinorPauseMillis=5 \
-XX:ConcGCThreads=8 \
-XX:InitiatingHeapOccupancyPercent=70 \
-XX:MaxTenuringThreshold=10 \
-XX:SurvivorRatio=6 \
-XX:-UseAdaptiveSizePolicy \
-XX:MaxMetaspaceSize=256M \
-Xmx4G \
-Xms2G \優(yōu)化結(jié)果
總結(jié)
請(qǐng)注意,JVM性能調(diào)優(yōu)是一個(gè)復(fù)雜的過(guò)程,需要結(jié)合具體的應(yīng)用程序特性和需求來(lái)進(jìn)行調(diào)優(yōu)。不同的應(yīng)用場(chǎng)景可能需要不同的調(diào)優(yōu)策略。在進(jìn)行JVM性能調(diào)優(yōu)時(shí),應(yīng)該先進(jìn)行性能測(cè)試和分析,找出性能瓶頸,然后有針對(duì)性地進(jìn)行優(yōu)化。同時(shí),及時(shí)記錄和備份調(diào)優(yōu)前的配置和參數(shù),以便在調(diào)優(yōu)過(guò)程中出現(xiàn)問(wèn)題時(shí)能夠恢復(fù)到原始狀態(tài)。
文章標(biāo)題:深入了解Java的GC原理,掌握J(rèn)VM性能調(diào)優(yōu)!
本文網(wǎng)址:http://www.5511xx.com/article/dhjcdss.html


咨詢
建站咨詢
