成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入淺出JVM垃圾回收器

云計算 虛擬化
本文對Java虛擬機(jī)垃圾回收器及其回收策略進(jìn)行逐一介紹,同時對垃圾回收的優(yōu)化思路做一些簡單討論,以期讀者能對Java虛擬機(jī)的垃圾回收增加理解,同時對垃圾回收的優(yōu)化有一些初步認(rèn)識,為后續(xù)工作中的Java應(yīng)用調(diào)優(yōu)打下基礎(chǔ)。

[[427167]]

引言

程序的運(yùn)行必然需要申請內(nèi)存資源,使用結(jié)束后的內(nèi)存資源如果不及時釋放就會造成內(nèi)存中的垃圾越來越多,最終造成內(nèi)存溢出,而垃圾回收就是把無用的內(nèi)存垃圾清理掉,這樣內(nèi)存就可以被程序反復(fù)使用。

垃圾回收(Garbage Collection 簡稱GC)是Java體系最重要的組成部分之一,和C/C++的手工內(nèi)存管理方式不同,JVM虛擬機(jī)提供了一套全自動的內(nèi)存管理方案,以減少開發(fā)人員在內(nèi)存管理方面的相關(guān)工作。

(一) 常見的垃圾回收算法和垃圾回收器

1. 常見的垃圾回收算法

a) 標(biāo)記清除算法(Mark-Sweep)

最早出現(xiàn)也是最基礎(chǔ)的垃圾回收算法,算法整體分為兩個階段“標(biāo)記”和“清除”,首先標(biāo)記出所有需要回收的對象,在標(biāo)記完成后,統(tǒng)一回收掉所有被標(biāo)記的對象,該算法簡單快速,但是缺點明顯:一是標(biāo)記和清除兩個過程的效率都不高。二是清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片。內(nèi)存碎片過多可能導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對象時,無法找到足夠的連續(xù)內(nèi)存而提前觸發(fā)另一次垃圾回收動作。圖1中展示了標(biāo)記-清楚算法的過程。

圖 1

b) 標(biāo)記復(fù)制算法(Copying)

為了解決標(biāo)記清除算法的大對象回收效率和內(nèi)存碎片化問題。提出了另一種“半?yún)^(qū)復(fù)制”的算法,核心思想就是將原有的內(nèi)存空間分為兩塊,每次只使用一半?yún)^(qū)域。垃圾回收時將使用的對象復(fù)制到未使用的半?yún)^(qū)中,之后清除當(dāng)前使用半?yún)^(qū)的所有對象,最后交換兩個內(nèi)存角色,完成回收工作。雖然解決了內(nèi)存碎片化的問題,但是如果活動對象較多,就會導(dǎo)致復(fù)制的對象過多,復(fù)制的成本很高且僅能使用一半的內(nèi)存,因此單純的復(fù)制算法也有很多問題。圖2展示了復(fù)制算法的過程。

圖 2

c) 標(biāo)記壓縮算法(Mark-Compact)

標(biāo)記壓縮算法的標(biāo)記過程與標(biāo)記清除算法一樣,但是后續(xù)步驟不是直接對可回收對象進(jìn)行清理,而是讓所有存活的對象都向空閑內(nèi)存的一端移動,然后直接清理掉邊界以外的所有內(nèi)存,這種方法避免了內(nèi)存碎片的產(chǎn)生,又不需要兩塊相同的內(nèi)存空間,標(biāo)記壓縮算法的最終效果等于標(biāo)記清除執(zhí)行后再進(jìn)行一次內(nèi)存碎片整理。圖3展示了標(biāo)記壓縮算法的過程。

圖3

2.分代回收理論(GenerationalCollecting)

分代回收是一種回收思想,目前被虛擬機(jī)廣泛使用,在前面介紹的算法中,沒有一種算法可以完全替代其他算法,分代收集就是基于這種思想,將內(nèi)存根據(jù)對象的特點分成幾塊,根據(jù)每塊內(nèi)存的特點使用不同的回收算法,提高內(nèi)存的回收效率。主流的JVM虛擬機(jī)里面一般會把JAVA堆內(nèi)存劃分為年輕代(Young Generation)和老年代(Old Generation)兩個區(qū)域,每次垃圾收集時會有大批的對象被回收,少量存活的對象將逐步轉(zhuǎn)移到老年代存放。圖4展示了主流JVM虛擬機(jī)的內(nèi)存的分代情況。

圖 4

3. 常見的垃圾回收器

再說垃圾回收器之前,需要再說一下為什么需要不斷優(yōu)化垃圾回收器,一切都源于一個詞語“Stop The World”簡稱STW,JVM虛擬機(jī)會自動發(fā)起和自動完成回收垃圾的工作,用戶在不可干預(yù)的情況下,需要暫停所有正常工作線程來等待垃圾回收的完成。試想下每工作幾小時就需要暫停幾分鐘,這樣的程序是無法讓人接受的。

垃圾回收的算法為垃圾回收器提供了理論基礎(chǔ),垃圾回收器就是這些理論算法的具體實現(xiàn)。圖5展示了七種不同的垃圾回收器,如果兩回收器之前存在連線,就說明可以搭配使用。

圖5

a) 串行回收器(Serial + Serial Old)

最古老的垃圾回收器,也是最基本的垃圾回收器之一,是一個單線程的垃圾回收器,在年輕代工作時使用的是標(biāo)記復(fù)制算法,在老年代工作時使用的是標(biāo)記壓縮算法。在CPU性能受限的情況下,它的性能表現(xiàn)依然很優(yōu)秀。圖6展示了串行垃圾回收器的回收過程。

圖6

b) 并發(fā)回收器(ParNew和CMS)

ParNew回收器是一款只能工作在年輕代的并行收集器 ,它是Serial收集器的多線程版本,由于使用多線程進(jìn)行垃圾回收,在計算能力較強(qiáng)的CPU上,產(chǎn)生的停頓時間要小于串行回收器。圖7展示了ParNew并行的回收的過程。

圖7

CMS(Concurrent Mark Sweep)是一款只能工作在老年代的收集器,第一款設(shè)計較為的復(fù)雜的收集器,也是JVM虛擬機(jī)追求低停頓的第一次嘗試,但是也有明顯的缺點,圖8展示了CMS收集器的回收過程。總的來說有三點:首先CMS收集器對CPU性能比較敏感,如果CPU性能不足或者本身的負(fù)載就很高,那這會讓整個垃圾回收的過程變長。其次,在并發(fā)標(biāo)記和并發(fā)清除的階段,用戶線程會有新的垃圾產(chǎn)生,就會產(chǎn)生“浮動垃圾(Floating Garbage)”,所以就不能像其他回收器那樣等到老年代100%再進(jìn)行回收,需要預(yù)留一部分內(nèi)存提供給用戶線程使用。最后,CMS是一個基于標(biāo)記清除算法實現(xiàn)的回收器,這就會產(chǎn)生大量的內(nèi)存碎片,如果有大對象需要處理,碎片過多時就需要對Old區(qū)再進(jìn)行一次垃圾回收進(jìn)行內(nèi)存整理。ParNew和CMS垃圾回收器一般搭配來進(jìn)行使用,不過這兩個收集器已經(jīng)在JDK9中被標(biāo)記為廢棄,JDK14該回收器將被正式刪除。

圖8

c) 并行回收(ParallelGC+ParallelOldGC)

ParallelGC和ParallelOldGC是JDK8中默認(rèn)使用的兩個回收器分別用在年輕代和老年代, 并且他們都是多線程回收器。ParallelGC采用的是復(fù)制算法進(jìn)行垃圾回收,它和ParNew不同的是可以控制系統(tǒng)的吞吐量和最大停頓時間,并且增加了自調(diào)優(yōu)的功能,相當(dāng)于ParNew的升級版本。ParallelOldGC使用的是標(biāo)記壓縮算法,這個回收器在JDK6時開始提供使用。圖9展示了ParallelGC和ParallelOldGC的回收過程。

圖9

d)分區(qū)回收器(Garbage First)

隨著大數(shù)據(jù)時代的來臨,JVM虛擬機(jī)的內(nèi)存也越來越大,在相同條件下,內(nèi)存空間越大,一次GC所需的時間就越長,產(chǎn)生的停頓就越長。為了更好的控制GC產(chǎn)生的STW時間。Garbage First回收器(簡稱G1)出現(xiàn)了,JDK6時開始推出試驗版本,JDK7 Update4中逐漸的成熟起來,終于在JDK8 Update40以后G1提供并發(fā)的類卸載功能成為了可以替代CMS的回收器,JDK9版本中G1被設(shè)置成默認(rèn)的垃圾回收器。G1回收器引入了分區(qū)(Region)的概念,將整個內(nèi)存空間分為不同大小的小分區(qū),每個小分區(qū)單獨(dú)使用,獨(dú)立回收。不過G1也還是遵循了分代回收的理論,還是會區(qū)分年輕代和老年代的概念,從整體看G1是基于標(biāo)記壓縮算法實現(xiàn)的,但是從局部看每個分區(qū)之間又是基于標(biāo)記復(fù)制算法實現(xiàn)的。

圖10

(二) 垃圾回收器內(nèi)存分配詳解

1. 分代垃圾回收器

分代的垃圾回收器是如何進(jìn)行內(nèi)存分配和管理的呢?我們再來回顧下分代思想。如圖11所示,整個的JVM空間被分成2個區(qū)域年輕代(Young Generation)和老年代(Old Generation),而Young區(qū)又被分成了伊甸園區(qū)(Eden,統(tǒng)簡稱Eden)和生存區(qū)(Survivor),而Survivor又被分為From(Survivor0,統(tǒng)簡稱“S0”)和To(Survivor1,統(tǒng)簡稱“S1”)兩個區(qū)域。年輕代和老年代比例為1:2(默認(rèn)參數(shù)),在年輕代中內(nèi)存中又被分成了三份(默認(rèn)為8:1:1)。

G行已經(jīng)開始逐步開始從JDK6向JDK8進(jìn)行替換,關(guān)于這部分內(nèi)容主要針對JDK8版本進(jìn)行說明。

圖 11

幾乎所有新生成的對象首先都是放在年輕代,大部分對象在 Eden 區(qū)中生成,當(dāng)Eden區(qū)內(nèi)存空間不足時,則會發(fā)起一次GC,回收器會將Eden區(qū)存活對象復(fù)制到S0,然后清空Eden區(qū)。如圖12展示的過程。

圖 12

下一次Eden區(qū)空間不足時,會將Eden區(qū)和S0區(qū)的存活對象復(fù)制到S1區(qū),然后清空Eden區(qū)和S0區(qū)。如圖13展示的過程。

圖 13

這時候會又出一個問題,對象什么時候去老年代呢?對象每次在S0和S1之間復(fù)制一次,這個對象的年齡就長一歲,當(dāng)15歲(默認(rèn)為15歲,可通過參數(shù)調(diào)整)之后這個對象就會被復(fù)制到老年代去。如圖14展示的過程。

圖 14

如此這樣循環(huán)往復(fù),當(dāng)老年代也空間不足時,回收器就會用對老年代進(jìn)行回收來釋放內(nèi)存空間,也就是通常說的Full GC。

2. 分區(qū)垃圾回收器

傳統(tǒng)的GC收集器將連續(xù)的內(nèi)存空間劃分為新生代、老年代和永久代(JDK 8去除了永久代,引入了元空間Metaspace)。如下圖15所示,不過現(xiàn)在請大家忘記它吧。

圖 15

G1的內(nèi)存存儲地址是不連續(xù)的,G1 將連續(xù)的Java堆劃分為多個大小相等的獨(dú)立區(qū)域(Region),每一個Region都可以根據(jù)需要,扮演新生代的Eden空間、Survivor空間,或者老年代Old空間,每個Region的大小可以取值范圍為1MB~32MB,且應(yīng)為2的N次冪,并且新增一個區(qū)域叫巨大對象(humongous object,H-obj),只要大小超過了一個Region容量一半即可判定為大對象,直接放入大對象區(qū)。對于那些超過了整個Region容量的超級大對象,將會被存放在N個連續(xù)的Humongous Region之中。如下圖16所示G1內(nèi)存的分配情況。

圖 16

在分配一般對象時,當(dāng)所有Eden Region使用達(dá)到最大閾值并且無法申請足夠內(nèi)存時,會觸發(fā)一次年輕代Region的GC。每次GC會回收所有Eden以及Survivor,并且將存活對象復(fù)制到空白的Survivor區(qū)。如下圖17所示。

5A974d6e659b30673a30fcdee4aa6e7.jpg" target="_blank">5A974d6e659b30673a30fcdee4aa6e7.jpg" width="auto" border="0" height="auto" alt="" title="">

圖 17

那內(nèi)存什么時候進(jìn)入老年代的Region呢?在G1回收器中有兩種情況會進(jìn)入到老年代Region:

同分代回收的規(guī)則,內(nèi)存每在年輕代的Region被復(fù)制一次,年齡就長一歲,當(dāng)15歲(默認(rèn)為15歲,可通過參數(shù)調(diào)整)之后這個對象就會被復(fù)制到老年代的Region。

動態(tài)年齡判斷規(guī)則,某次年輕代GC 過后,發(fā)現(xiàn) Survivor 區(qū)中相同年齡的對象達(dá)到了 Survivor 的 50%,那么該年齡及以上的對象,會被直接移動到老年代中。例如Survivor 區(qū)中存在年齡分別為 1、2、3、4 的對象,而年齡為 3 的對象超過了 Survivor 區(qū)的 50%,那么年齡大于等于 3 的對象,就會被全部移動到老年代的Region。

最后再談下分區(qū)回收獨(dú)有的混合回收(Mixed GC),在G1中不存在單獨(dú)回收老年代Region的行為,而是當(dāng)要發(fā)生老年代的回收時,同時也會對新生代以及大對象進(jìn)行回收,因此這個階段稱之為混合回收。當(dāng)老年代Region的使用率占比達(dá)到 45%時,就會觸發(fā)混合回收。

不過在G1中Full GC還是存在的,如果空閑的 Region 大小無法放得下存活對象的內(nèi)存大小時系統(tǒng)就不得不暫停應(yīng)用程序,進(jìn)行一次 Full GC。進(jìn)行 Full GC 時采用的是單線程進(jìn)行標(biāo)記、清理和整理內(nèi)存,這個過程是非常漫長的,因此應(yīng)該盡量避免 Full GC 的觸發(fā)。

(三) 垃圾回收器的優(yōu)化思路

垃圾回收器的優(yōu)化思路

垃圾回收器的選擇是JVM優(yōu)化的一個重要配置,選擇合適的垃圾回收器可以讓JVM性能有一個很大的提升。其實JVM調(diào)優(yōu)主要是調(diào)整兩個指標(biāo):

JVM虛擬機(jī)停頓時間(Stop The World)

吞吐量是指CPU用于運(yùn)行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運(yùn)行用戶代碼時間 /( 運(yùn)行用戶代碼時間 + 垃圾收集時間 )

下面分享下關(guān)于回收器選擇上的一些經(jīng)驗。

1. 小內(nèi)存,默認(rèn)優(yōu)先:

大部分應(yīng)用JVM堆內(nèi)存都在4G以內(nèi),優(yōu)先使用JDK8默認(rèn)的垃圾回收器。如今大部分系統(tǒng)都運(yùn)行在虛擬機(jī)上,G1固然是更先進(jìn)的垃圾回收器,但是G1在垃圾回收時產(chǎn)生的內(nèi)存占用也更高,所以小內(nèi)容使用G1作為回收器會增加GC的次數(shù),吞吐量會下降。

2. 大內(nèi)存,G1優(yōu)先:

當(dāng)內(nèi)存大于8G后,應(yīng)該優(yōu)先考慮G1垃圾回收器,因為當(dāng)內(nèi)存增大后,在進(jìn)行垃圾回收時會將對象從s0復(fù)制到s1內(nèi)存越大,復(fù)制的時間越長,會增加系統(tǒng)STW的時間,導(dǎo)致系統(tǒng)的停頓時間過長。

總結(jié)

隨著Java的不斷發(fā)展,有很多新的回收器出現(xiàn),如:shenandoahGC和ZGC,同為新一代的低延遲收集器, 分別由RedHat和Oracle開發(fā), 不過還在實驗階段, 尚未使用于生產(chǎn)環(huán)境,針對不同類型的應(yīng)用Java提供了多種垃圾回收策略。

 

本文對Java虛擬機(jī)垃圾回收器及其回收策略進(jìn)行逐一介紹,同時對垃圾回收的優(yōu)化思路做一些簡單討論,以期讀者能對Java虛擬機(jī)的垃圾回收增加理解,同時對垃圾回收的優(yōu)化有一些初步認(rèn)識,為后續(xù)工作中的Java應(yīng)用調(diào)優(yōu)打下基礎(chǔ)。

 

責(zé)任編輯:武曉燕 來源: 匠心獨(dú)運(yùn)維妙維效
相關(guān)推薦

2023-05-05 18:33:15

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2019-10-10 16:25:02

JVM數(shù)據(jù)多線程

2019-01-07 15:29:07

HadoopYarn架構(gòu)調(diào)度器

2017-07-02 18:04:53

塊加密算法AES算法

2012-05-21 10:06:26

FrameworkCocoa

2021-07-20 15:20:02

FlatBuffers阿里云Java

2022-09-26 09:01:15

語言數(shù)據(jù)JavaScript

2009-12-01 16:37:00

2009-11-30 16:46:29

學(xué)習(xí)Linux

2012-02-21 13:55:45

JavaScript

2022-01-11 07:52:22

CSS 技巧代碼重構(gòu)

2018-11-09 16:24:25

物聯(lián)網(wǎng)云計算云系統(tǒng)

2019-11-11 14:51:19

Java數(shù)據(jù)結(jié)構(gòu)Properties

2022-11-09 08:06:15

GreatSQLMGR模式

2022-12-02 09:13:28

SeataAT模式

2022-10-31 09:00:24

Promise數(shù)組參數(shù)

2009-11-18 13:30:37

Oracle Sequ

2019-12-04 10:13:58

Kubernetes存儲Docker
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩一区二区在线视频 | 欧美精品v | 性色综合| 欧美日韩国产一区二区三区 | 日本五月婷婷 | 久久国产一区二区三区 | 亚洲高清三级 | 在线久草 | 国产精品高潮呻吟久久 | 免费精品视频在线观看 | 亚洲综合精品 | 欧区一欧区二欧区三免费 | 亚洲精品成人av | 国产成人精品一区二区三区在线 | 一区二区三区四区在线 | 美女亚洲一区 | 久久久成人一区二区免费影院 | 免费成人高清在线视频 | 亚洲一一在线 | h漫在线观看 | 国产在线视频一区二区 | 毛片视频免费观看 | 久久这里有精品 | 久草免费电影 | 欧美日韩大片 | 久久久久久久97 | 欧美精品日韩 | 欧美黄色片在线观看 | 亚洲第一女人av | 操人视频在线观看 | 日本高清视频在线播放 | 亚洲欧洲中文 | 人人干在线视频 | 免费在线观看黄色av | 亚洲精品乱码久久久久久黑人 | 视频一区二区在线观看 | wwwxxx日本在线观看 | 亚洲精品久久久久久久久久久 | 国产成人a亚洲精品 | 日韩在线观看一区二区三区 | 中文一区二区视频 |