日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
深入了解Java的GC原理,掌握J(rèn)VM性能調(diào)優(yōu)!

對(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:+UseParallelGC

G1垃圾收集

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:+UseSerialGC

G1 優(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