jvm垃圾回收機(jī)制指的是什么

這篇文章主要介紹“jvm垃圾回收機(jī)制指的是什么”,在日常操作中,相信很多人在jvm垃圾回收機(jī)制指的是什么問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”jvm垃圾回收機(jī)制指的是什么”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設(shè)、做網(wǎng)站與策劃設(shè)計(jì),平陽網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:平陽等地區(qū)。平陽做網(wǎng)站價(jià)格咨詢:13518219792

jvm的垃圾回收機(jī)制是GC(Garbage Collection),也叫垃圾收集器。GC基本原理:將內(nèi)存中不再被使用的對(duì)象進(jìn)行回收;GC中用于回收的方法稱為收集器,由于GC需要消耗一些資源和時(shí)間,Java在對(duì)對(duì)象的生命周期特征進(jìn)行分析后,按照新生代、老年代的方式來對(duì)對(duì)象進(jìn)行收集,以盡可能的縮短GC對(duì)應(yīng)用造成的暫停。

什么是垃圾回收

java相較于c、c++語言的優(yōu)勢(shì)之一是自帶垃圾回收器,垃圾回收是指不定時(shí)去堆內(nèi)存中清理不可達(dá)對(duì)象。不可達(dá)的對(duì)象并不會(huì)馬上就會(huì)直接回收, 垃圾收集器在一個(gè)Java程序中的執(zhí)行是自動(dòng)的,不能強(qiáng)制執(zhí)行,程序員唯一能做的就是通過調(diào)用System.gc 方法來建議執(zhí)行垃圾收集器,但其是否可以執(zhí)行,什么時(shí)候執(zhí)行卻都是不可知的。這也是垃圾收集器的最主要的缺點(diǎn)。當(dāng)然相對(duì)于它給程序員帶來的巨大方便性而言,這個(gè)缺點(diǎn)是瑕不掩瑜的。

為什么需要垃圾回收

如果不進(jìn)行垃圾回收,內(nèi)存遲早都會(huì)被消耗空,因?yàn)槲覀冊(cè)诓粩嗟姆峙鋬?nèi)存空間而不進(jìn)行回收。除非內(nèi)存無限大,我們可以任性的分配而不回收,但是事實(shí)并非如此。所以,垃圾回收是必須的。

jvm垃圾回收原理

在JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)存在一個(gè)堆區(qū), 堆是一個(gè)巨大的對(duì)象池。在這個(gè)對(duì)象池中管理著數(shù)量巨大的對(duì)象實(shí)例,而池中對(duì)象的引用層次,有的是很深的。一個(gè)被頻繁調(diào)用的接口,每秒生成對(duì)象的速度,是很大的,同時(shí),對(duì)象之間的關(guān)系,形成了一張巨大的網(wǎng)。

Java 一直在營(yíng)造一種無限內(nèi)存的氛圍,但對(duì)象不能只增不減,所以需要垃圾回收;那 JVM 是如何判斷哪些對(duì)象應(yīng)該被回收?哪些應(yīng)該被保持呢?這就要用到JVM的垃圾回收機(jī)制了,也就是我們常說的GC(Garbage Collection),也叫垃圾收集器。

GC (Garbage Collection:即垃圾回收)的基本原理:將內(nèi)存中不再被使用的對(duì)象進(jìn)行回收,GC中用于回收的方法稱為收集器,由于GC需要消耗一些資源和時(shí)間,Java在對(duì)對(duì)象的生命周期特征進(jìn)行分析后,按照新生代、老年代的方式來對(duì)對(duì)象進(jìn)行收集,以盡可能的縮短GC對(duì)應(yīng)用造成的暫停

● 對(duì)新生代的對(duì)象的收集稱為minor GC
● 對(duì)老年代的對(duì)象的收集稱為Full GC
● 程序中主動(dòng)調(diào)用System.gc()強(qiáng)制執(zhí)行的GC為Full GC

不同的對(duì)象引用類型, GC會(huì)采用不同的方法進(jìn)行回收,JVM對(duì)象的引用分為了四種類型:
● 強(qiáng)引用:默認(rèn)情況下,對(duì)象采用的均為強(qiáng)引用(這個(gè)對(duì)象的實(shí)例沒有其他對(duì)象引用,GC時(shí)才會(huì)被回收)
● 軟引用:軟引用是Java中提供的一種比較適合于緩存場(chǎng)景的應(yīng)用(只有在內(nèi)存不夠用的情況下才會(huì)被GC)
● 弱引用:在GC時(shí)一定會(huì)被GC回收
● 虛引用:由于虛引用只是用來得知對(duì)象是否被GC

對(duì)象被標(biāo)記為垃圾方法

JVM的內(nèi)存結(jié)構(gòu)包括五大區(qū)域:程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧、堆區(qū)、方法區(qū)。其中程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧3個(gè)區(qū)域隨線程而生、隨線程而滅,因此這幾個(gè)區(qū)域的內(nèi)存分配和回收都具備確定性,就不需要過多考慮回收的問題,因?yàn)榉椒ńY(jié)束或者線程結(jié)束時(shí),內(nèi)存自然就跟隨著回收了。而Java堆區(qū)和方法區(qū)則不一樣,這部分內(nèi)存的分配和回收是動(dòng)態(tài)的,正是垃圾收集器所需關(guān)注的部分。

1. 引用計(jì)數(shù)器

引用計(jì)數(shù)是垃圾收集器中的早期策略。在這種方法中,堆中每個(gè)對(duì)象實(shí)例都有一個(gè)引用計(jì)數(shù)。當(dāng)一個(gè)對(duì)象被創(chuàng)建時(shí),就將該對(duì)象實(shí)例分配給一個(gè)變量,該變量計(jì)數(shù)設(shè)置為1。當(dāng)任何其它變量被賦值為這個(gè)對(duì)象的引用時(shí),計(jì)數(shù)加1(a = b,則b引用的對(duì)象實(shí)例的計(jì)數(shù)器+1),但當(dāng)一個(gè)對(duì)象實(shí)例的某個(gè)引用超過了生命周期或者被設(shè)置為一個(gè)新值時(shí),對(duì)象實(shí)例的引用計(jì)數(shù)器減1。任何引用計(jì)數(shù)器為0的對(duì)象實(shí)例可以被當(dāng)作垃圾收集。當(dāng)一個(gè)對(duì)象實(shí)例被垃圾收集時(shí),它引用的任何對(duì)象實(shí)例的引用計(jì)數(shù)器減1。

優(yōu)點(diǎn):引用計(jì)數(shù)收集器可以很快的執(zhí)行,交織在程序運(yùn)行中。對(duì)程序需要不被長(zhǎng)時(shí)間打斷的實(shí)時(shí)環(huán)境比較有利。
缺點(diǎn):無法檢測(cè)出循環(huán)引用。如父對(duì)象有一個(gè)對(duì)子對(duì)象的引用,子對(duì)象反過來引用父對(duì)象。這樣,他們的引用計(jì)數(shù)永遠(yuǎn)不可能為0。

jvm垃圾回收機(jī)制指的是什么

對(duì)以上代碼通過引用計(jì)數(shù)法分析:

jvm垃圾回收機(jī)制指的是什么

jvm垃圾回收機(jī)制指的是什么

jvm垃圾回收機(jī)制指的是什么

2. 可達(dá)性分析

可達(dá)性算法是目前主流的虛擬機(jī)都采用的算法,程序把所有的引用關(guān)系看作一張圖,從一個(gè)節(jié)點(diǎn)GC Roots開始,尋找對(duì)應(yīng)的引用節(jié)點(diǎn),找到這個(gè)節(jié)點(diǎn)以后,繼續(xù)尋找這個(gè)節(jié)點(diǎn)的引用節(jié)點(diǎn),當(dāng)所有的引用節(jié)點(diǎn)尋找完畢之后,剩余的節(jié)點(diǎn)則被認(rèn)為是沒有被引用到的節(jié)點(diǎn),即無用的節(jié)點(diǎn),無用的節(jié)點(diǎn)將會(huì)被判定為是可回收的對(duì)象。

在Java語言中,可作為GC Roots的對(duì)象包括下面幾種:
● 虛擬機(jī)棧中引用的對(duì)象(棧幀中的本地變量表);
● 方法區(qū)中類靜態(tài)屬性引用的對(duì)象;
● 方法區(qū)中常量引用的對(duì)象;
● 本地方法棧中JNI(Native方法)引用的對(duì)象。

jvm垃圾回收機(jī)制指的是什么

可以得出對(duì)象實(shí)例1、2、4、6都具有對(duì)象可達(dá)性,也就是存活對(duì)象,不能被GC回收的對(duì)象。而隨想實(shí)例3、5雖然直接相連,但并沒有任何一個(gè)GC Roots與之相連,即GC Roots不可達(dá)對(duì)象,就會(huì)被GC回收的對(duì)象。

三、垃圾回收算法

1. 標(biāo)記-清除算法

標(biāo)記/清除算法的基本思想就跟它的名字一樣,分為“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。
標(biāo)記階段:
標(biāo)記的過程其實(shí)就是前面介紹的可達(dá)性分析算法的過程,遍歷所有的 GC Roots 對(duì)象,對(duì)從 GCRoots 對(duì)象可達(dá)的對(duì)象都打上一個(gè)標(biāo)識(shí),一般是在對(duì)象的 header 中,將其記錄為可達(dá)對(duì)象。
清除階段:
清除的過程是對(duì)堆內(nèi)存進(jìn)行遍歷,如果發(fā)現(xiàn)某個(gè)對(duì)象沒有被標(biāo)記為可達(dá)對(duì)象(通過讀取對(duì)象header 信息),則將其回收。

jvm垃圾回收機(jī)制指的是什么

上圖是標(biāo)記/清除算法的示意圖,在標(biāo)記階段,從對(duì)象 GC Root 1 可以訪問到 B 對(duì)象,從 B 對(duì)象又可以訪問到 E 對(duì)象,因此從 GC Root 1 到 B、E 都是可達(dá)的,同理,對(duì)象 F、G、J、K 都是可達(dá)對(duì)象;到了清除階段,所有不可達(dá)對(duì)象都會(huì)被回收。
在垃圾收集器進(jìn)行 GC 時(shí),必須停止所有 Java 執(zhí)行線程(也稱"Stop The World"),原因是在標(biāo)記階段進(jìn)行可達(dá)性分析時(shí),不可以出現(xiàn)分析過程中對(duì)象引用關(guān)系還在不斷變化的情況,否則的話可達(dá)性分析結(jié)果的準(zhǔn)確性就無法得到保證。在等待標(biāo)記清除結(jié)束后,應(yīng)用線程才會(huì)恢復(fù)運(yùn)行。

標(biāo)記/清除算法缺點(diǎn):
效率問題
標(biāo)記和清除兩個(gè)階段的效率都不高,因?yàn)檫@兩個(gè)階段都需要遍歷內(nèi)存中的對(duì)象,很多時(shí)候內(nèi)存中的對(duì)象實(shí)例數(shù)量是非常龐大的,這無疑很耗費(fèi)時(shí)間,而且 GC 時(shí)需要停止應(yīng)用程序,這會(huì)導(dǎo)致非常差的用戶體驗(yàn)。
空間問題
標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片(從上圖可以看出),內(nèi)存空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對(duì)象時(shí),無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾回收動(dòng)作。

2. 復(fù)制算法

復(fù)制算法是將可用內(nèi)存按容量劃分為大小相等的兩塊,每次使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活的對(duì)象復(fù)制到另一塊內(nèi)存上,然后把這一塊內(nèi)存所有的對(duì)象一次性清理掉
jvm垃圾回收機(jī)制指的是什么

復(fù)制算法每次都是對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,這樣就減少了標(biāo)記對(duì)象遍歷的時(shí)間,在清除使用區(qū)域?qū)ο髸r(shí),不用進(jìn)行遍歷,直接清空整個(gè)區(qū)域內(nèi)存,而且在將存活對(duì)象復(fù)制到保留區(qū)域時(shí)也是按地址順序存儲(chǔ)的,這樣就解決了內(nèi)存碎片的問題,在分配對(duì)象內(nèi)存時(shí)不用考慮內(nèi)存碎片等復(fù)雜問題,只需要按順序分配內(nèi)存即可。

復(fù)制算法缺點(diǎn):
復(fù)制算法簡(jiǎn)單高效,優(yōu)化了標(biāo)記清除算法的效率低、內(nèi)存碎片多問題,存在缺點(diǎn):
● 將內(nèi)存縮小為原來的一半,浪費(fèi)了一半的內(nèi)存空間,代價(jià)太高;
● 如果對(duì)象的存活率很高,極端一點(diǎn)的情況假設(shè)對(duì)象存活率為 100%,那么我們需要將所有存活的對(duì)象復(fù)制一遍,耗費(fèi)的時(shí)間代價(jià)也是不可忽視的。

3. 標(biāo)記-整理算法

標(biāo)記-整理算法算法與標(biāo)記/清除算法很像,事實(shí)上,標(biāo)記/整理算法的標(biāo)記過程任然與標(biāo)記/清除算法一樣,但后續(xù)步驟不是直接對(duì)可回收對(duì)象進(jìn)行回收,而是讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊線以外的內(nèi)存。
jvm垃圾回收機(jī)制指的是什么

可以看到,回收后可回收對(duì)象被清理掉了,存活的對(duì)象按規(guī)則排列存放在內(nèi)存中。這樣一來,當(dāng)我們給新對(duì)象分配內(nèi)存時(shí),jvm 只需要持有內(nèi)存的起始地址即可。標(biāo)記/整理算法彌補(bǔ)了標(biāo)記/清除算法存在內(nèi)存碎片的問題消除了復(fù)制算法內(nèi)存減半的高額代價(jià),可謂一舉兩得。

標(biāo)記/整理缺點(diǎn):
● 效率不高:不僅要標(biāo)記存活對(duì)象,還要整理所有存活對(duì)象的引用地址,在效率上不如復(fù)制算法。

4. 分代回收算法

分代收集算法的思想是按對(duì)象的存活周期不同將內(nèi)存劃分為幾塊一般是把 Java 堆分為新生代和老年代(還有一個(gè)永久代,是 HotSpot 特有的實(shí)現(xiàn),其他的虛擬機(jī)實(shí)現(xiàn)沒有這一概念,永久代的收集效果很差,一般很少對(duì)永久代進(jìn)行垃圾回收),這樣就可以根據(jù)各個(gè)年代的特點(diǎn)采用最合適的收集算法。

特點(diǎn):
新生代:朝生夕滅,存活時(shí)間很短。采用復(fù)制算法來收集
老年代:經(jīng)過多次 Minor GC 而存活下來,存活周期長(zhǎng)。采用標(biāo)記/清除算法或者標(biāo)記/整理算法收集老年代

新生代中每次垃圾回收都發(fā)現(xiàn)有大量的對(duì)象死去,只有少量存活,因此采用復(fù)制算法回收新生代,只需要付出少量對(duì)象的復(fù)制成本就可以完成收集;
老年代中對(duì)象的存活率高,不適合采用復(fù)制算法,而且如果老年代采用復(fù)制算法,它是沒有額外的空間進(jìn)行分配擔(dān)保的,因此必須使用標(biāo)記/清理算法或者標(biāo)記/整理算法來進(jìn)行回收。

jvm垃圾回收機(jī)制指的是什么

新生代中的對(duì)象“朝生夕死”,每次GC時(shí)都會(huì)有大量對(duì)象死去,少量存活,使用復(fù)制算法。新生代又分為Eden區(qū)和Survivor區(qū)(Survivor from、Survivor to),大小比例默認(rèn)為8:1:1。
老年代中的對(duì)象因?yàn)閷?duì)象存活率高、沒有額外空間進(jìn)行分配擔(dān)保,就使用標(biāo)記-清除或標(biāo)記-整理算法。
新產(chǎn)生的對(duì)象優(yōu)先進(jìn)去Eden區(qū),當(dāng)Eden區(qū)滿了之后再使用Survivor from,當(dāng)Survivor from 也滿了之后就進(jìn)行Minor GC(新生代GC),將Eden和Survivor from中存活的對(duì)象copy進(jìn)入Survivor to,然后清空Eden和Survivor from,這個(gè)時(shí)候原來的Survivor from成了新的Survivor to,原來的Survivor to成了新的Survivor from。復(fù)制的時(shí)候,如果Survivor to 無法容納全部存活的對(duì)象,則根據(jù)老年代的分配擔(dān)保(類似于銀行的貸款擔(dān)保)將對(duì)象copy進(jìn)去老年代,如果老年代也無法容納,則進(jìn)行Full GC(老年代GC)。
大對(duì)象直接進(jìn)入老年代:JVM中有個(gè)參數(shù)配置
-XX:PretenureSizeThreshold,令大于這個(gè)設(shè)置值的對(duì)象直接進(jìn)入老年代,目的是為了避免在Eden和Survivor區(qū)之間發(fā)生大量的內(nèi)存復(fù)制。
長(zhǎng)期存活的對(duì)象進(jìn)入老年代:JVM給每個(gè)對(duì)象定義一個(gè)對(duì)象年齡計(jì)數(shù)器,如果對(duì)象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor容納,將被移入Survivor并且年齡設(shè)定為1。沒熬過一次Minor GC,年齡就加1,當(dāng)他的年齡到一定程度(默認(rèn)為15歲,可以通過XX:MaxTenuringThreshold來設(shè)定),就會(huì)移入老年代。但是JVM并不是永遠(yuǎn)要求年齡必須達(dá)到最大年齡才會(huì)晉升老年代,如果Survivor 空間中相同年齡(如年齡為x)所有對(duì)象大小的總和大于Survivor的一半,年齡大于等于x的所有對(duì)象直接進(jìn)入老年代,無需等到最大年齡要求。

分代回收:

我們從一個(gè)object1來說明其在分代垃圾回收算法中的回收軌跡。

1、object1新建,出生于新生代的Eden區(qū)域。
jvm垃圾回收機(jī)制指的是什么
2、minor GC,object1 還存活,移動(dòng)到From suvivor空間,此時(shí)還在新生代。

jvm垃圾回收機(jī)制指的是什么

3、minor GC,object1 仍然存活,此時(shí)會(huì)通過復(fù)制算法,將object1移動(dòng)到ToSuv區(qū)域,此時(shí)object1的年齡age+1。
jvm垃圾回收機(jī)制指的是什么
4、minor GC,object1 仍然存活,此時(shí)survivor中和object1同齡的對(duì)象并沒有達(dá)到survivor的一半,所以此時(shí)通過復(fù)制算法,將fromSuv和Tosuv 區(qū)域進(jìn)行互換,存活的對(duì)象被移動(dòng)到了Tosuv。
jvm垃圾回收機(jī)制指的是什么
5、minor GC,object1 仍然存活,此時(shí)survivor中和object1同齡的對(duì)象已經(jīng)達(dá)到survivor的一半以上(toSuv的區(qū)域已經(jīng)滿了),object1被移動(dòng)到了老年代區(qū)域。
jvm垃圾回收機(jī)制指的是什么
6、object1存活一段時(shí)間后,發(fā)現(xiàn)此時(shí)object1不可達(dá)GcRoots,而且此時(shí)老年代空間比率已經(jīng)超過了閾值,觸發(fā)了majorGC(也可以認(rèn)為是fullGC,但具體需要垃圾收集器來聯(lián)系),此時(shí)object1被回收了。fullGC會(huì)觸發(fā) stop the world。
jvm垃圾回收機(jī)制指的是什么
在以上的新生代中,我們有提到對(duì)象的age,對(duì)象存活于survivor狀態(tài)下,不會(huì)立即晉升為老年代對(duì)象,以避免給老年代造成過大的影響,它們必須要滿足以下條件才可以晉升:
1、minor gc 之后,存活于survivor 區(qū)域的對(duì)象的age會(huì)+1,當(dāng)超過(默認(rèn))15的時(shí)候,轉(zhuǎn)移到老年代。
2、動(dòng)態(tài)對(duì)象,如果survivor空間中相同年齡所有的對(duì)象大小的綜合和大于survivor空間的一半,年級(jí)大于或等于該年紀(jì)的對(duì)象就可以直接進(jìn)入老年代。

到此,關(guān)于“jvm垃圾回收機(jī)制指的是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

當(dāng)前標(biāo)題:jvm垃圾回收機(jī)制指的是什么
分享地址:http://bm7419.com/article40/jjsgeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、網(wǎng)頁設(shè)計(jì)公司、商城網(wǎng)站、定制開發(fā)、ChatGPT移動(dòng)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)