溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法

發(fā)布時(shí)間:2021-09-09 12:55:02 來(lái)源:億速云 閱讀:173 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

Java語(yǔ)言的垃圾回收

為了讓程序員更專注于代碼的實(shí)現(xiàn),而不用過(guò)多的考慮內(nèi)存釋放的問(wèn)題,所以,在Java語(yǔ)言中,有了自動(dòng)的垃圾回收機(jī)制,也就是我們熟悉的GC。
有了垃圾回收機(jī)制后,程序員只需要關(guān)心內(nèi)存的申請(qǐng)即可,內(nèi)存的釋放由系統(tǒng)自動(dòng)識(shí)別完成。
換句話說(shuō),自動(dòng)的垃圾回收的算法就會(huì)變得非常重要了,如果因?yàn)樗惴ǖ牟缓侠恚瑢?dǎo)致內(nèi)存資源一直沒(méi)有釋放,同樣也可能會(huì)導(dǎo)致內(nèi)存溢出的。
當(dāng)然,除了Java語(yǔ)言,C#、Python等語(yǔ)言也都有自動(dòng)的垃圾回收機(jī)制。

Java的垃圾回收常用算法

引用計(jì)數(shù)法

原理

假設(shè)有一個(gè)對(duì)象A,任何一個(gè)對(duì)象對(duì)A的引用,那么對(duì)象A的引用計(jì)數(shù)器+1,當(dāng)引用失敗時(shí),對(duì)象A的引用計(jì)數(shù)器就-1,如果對(duì)象A的計(jì)數(shù)器的值為0,就說(shuō)明對(duì)象A沒(méi)有引用了,可以被回收。

優(yōu)劣分析
  1. 優(yōu)勢(shì)
    實(shí)時(shí)性較高,無(wú)需等到內(nèi)存不夠的時(shí)候,才開(kāi)始回收,運(yùn)行時(shí)根據(jù)對(duì)象的計(jì)數(shù)器是否為0,就可以直接回收。
    在垃圾回收過(guò)程中,應(yīng)用無(wú)需掛起。如果申請(qǐng)內(nèi)存時(shí),內(nèi)存不足,則立刻報(bào)
    outofmember 錯(cuò)誤。
    區(qū)域性,更新對(duì)象的計(jì)數(shù)器時(shí),只是影響到該對(duì)象,不會(huì)掃描全部對(duì)象。

  2. 劣勢(shì)
    每次對(duì)象被引用時(shí),都需要去更新計(jì)數(shù)器,有一點(diǎn)時(shí)間開(kāi)銷。
    浪費(fèi)CPU資源,即使內(nèi)存夠用,仍然在運(yùn)行時(shí)進(jìn)行計(jì)數(shù)器的統(tǒng)計(jì)。
    無(wú)法解決循環(huán)引用問(wèn)題。(最大的缺點(diǎn))
    循環(huán)問(wèn)題演示:

  
    
  
  
  
class TestA {    public TestB b ;}class TestB{    public TestA a;}
public class Main {    public static void main(String[] args) {        TestA a = new TestA();        TestB b = new TestB();        a.b = b;        b.a = a;        a = null;        b = null;//     雖然被設(shè)置為null,但是a與b之間依舊存在著循環(huán)引用的問(wèn)題    }}
           

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

原理

標(biāo)記清除算法,是將垃圾回收分為2個(gè)階段,分別是標(biāo)記和清除。
標(biāo)記:從根節(jié)點(diǎn)開(kāi)始標(biāo)記引用的對(duì)象。
清除:未被標(biāo)記引用的對(duì)象就是垃圾對(duì)象,可以被清理。


Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法

初始狀態(tài)下,所有的目標(biāo)對(duì)象都是為0(未被標(biāo)記)
待jvm出現(xiàn)有效內(nèi)存耗盡,就會(huì)掛起線程,執(zhí)行GC線程,進(jìn)行標(biāo)記


Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法

從根節(jié)點(diǎn)進(jìn)行標(biāo)記到最后,然后回收未被標(biāo)記的對(duì)象。
清理完畢之后掛起gc線程,重新執(zhí)行原先被掛起的線程。
而被標(biāo)記的對(duì)象會(huì)被重新置0;


Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法

優(yōu)劣分析
  1. 優(yōu)勢(shì)
    很明顯的解決了循環(huán)應(yīng)用導(dǎo)致的不能被回收的問(wèn)題

  2. 缺點(diǎn)
    缺點(diǎn)也很明顯
    效率較低,標(biāo)記和清除兩個(gè)動(dòng)作都需要遍歷所有的對(duì)象,并且在GC時(shí),需要停止應(yīng)用程序,對(duì)于交互性要求比較高的應(yīng)用而言這個(gè)體驗(yàn)是非常差的。
    通過(guò)標(biāo)記清除算法清理出來(lái)的內(nèi)存,碎片化較為嚴(yán)重,因?yàn)楸换厥盏膶?duì)象可能存在于內(nèi)存的各個(gè)角落,所以清理出來(lái)的內(nèi)存是不連貫的

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

原理

標(biāo)記壓縮算法是在標(biāo)記清除算法的基礎(chǔ)之上,做了優(yōu)化改進(jìn)的算法。和標(biāo)記清除算法一樣,也是從根節(jié)點(diǎn)開(kāi)始,對(duì)對(duì)象的引用進(jìn)行標(biāo)記,在清理階段,并不是簡(jiǎn)單的清理未標(biāo)記的對(duì)象,而是將存活的對(duì)象壓縮到內(nèi)存的一端,然后清理邊界以外的垃圾,從而解決了碎片化的問(wèn)題。
Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法

優(yōu)劣分析
  1. 優(yōu)點(diǎn)
    在標(biāo)記清除算法的基礎(chǔ)上解決了產(chǎn)生碎片的問(wèn)題

  2. 缺點(diǎn)
    算法多出一步壓縮,所以在性能上也會(huì)有所影響

復(fù)制算法

原理

復(fù)制算法的核心就是:將原有的內(nèi)存空間一分為二,每次只用其中的一塊,在垃圾回收時(shí),將正在使用的對(duì)象復(fù)制到另一個(gè)內(nèi)存空間中,然后將該內(nèi)存空間清空,交換兩個(gè)內(nèi)存的角色,完成垃圾的回收。
典型的復(fù)制算法的落地實(shí)現(xiàn)就是:jvm中堆內(nèi)存的年輕代的gc策略(具體可以看我jvm系列的博客的內(nèi)存模型的那一部分內(nèi)容)

  1. 在GC開(kāi)始的時(shí)候,對(duì)象只會(huì)存在于Eden區(qū)和名為“From”的Survivor區(qū),Survivor 區(qū)“To”是空的。

  2. 緊接著進(jìn)行GC,Eden區(qū)中所有存活的對(duì)象都會(huì)被復(fù)制到“To”,而在“From”區(qū)中仍存活的對(duì)象會(huì)根據(jù)他們的年齡值來(lái)決定去向。年齡達(dá)到一定值(年齡閾值,可以通過(guò)- XX:MaxTenuringThreshold來(lái)設(shè)置)的對(duì)象會(huì)被移動(dòng)到年老代中,沒(méi)有達(dá)到閾值的對(duì)象會(huì)被復(fù)制到“To”區(qū)域。

  3. 經(jīng)過(guò)這次GC后,Eden區(qū)和From區(qū)已經(jīng)被清空。這個(gè)時(shí)候,“From”和“To”會(huì)交他們的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎樣,都會(huì)保證名為T(mén)o的Survivor區(qū)域是空的。

  4. GC會(huì)一直重復(fù)這樣的過(guò)程,直到“To”區(qū)被填滿,“To”區(qū)被填滿之后,會(huì)將所有象移動(dòng)到年老代中。

優(yōu)劣分析
  1. 優(yōu)勢(shì)
    在垃圾對(duì)象多的情況下,效率較高
    清理后,內(nèi)存無(wú)碎片

  2. 劣勢(shì)
    在垃圾對(duì)象少的情況下,不適用,如:老年代內(nèi)存
    分配的2塊內(nèi)存空間,在同一個(gè)時(shí)刻,只能使用一半,內(nèi)存使用率僅有50%

分代算法

前面介紹了多種回收算法,每一種算法都有自己的優(yōu)點(diǎn)也有缺點(diǎn),誰(shuí)都不能替代誰(shuí),所以根據(jù)垃圾回收對(duì)象的特點(diǎn)進(jìn)行選擇,才是明智的選擇。
分代算法其實(shí)就是這樣的,根據(jù)回收對(duì)象的特點(diǎn)進(jìn)行選擇,在jvm中,年輕代適合使用復(fù)制算法,老年代適合使用標(biāo)記清除或標(biāo)記壓縮算法。

“Java語(yǔ)言的垃圾回收機(jī)制以及垃圾回收常用算法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI