欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java GC垃圾回收算法分析

 更新時(shí)間:2022年12月20日 10:55:06   作者:碼畜c  
垃圾回收機(jī)制簡(jiǎn)稱(chēng)GC,主要用于Java堆的管理。在JVM中程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧生命周期隨跟隨線程,棧幀的進(jìn)棧和入棧能實(shí)現(xiàn)自動(dòng)清理。而 jdk8后元空間為本地內(nèi)存也不受GC控制,所以垃圾回收主要是在堆中

對(duì)象探活

在討論回收算法前,更為重要的問(wèn)題是如何判斷一個(gè)對(duì)象是否可以被回收?

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

每個(gè)對(duì)象會(huì)維護(hù)一個(gè)count,當(dāng)有一個(gè)對(duì)象的屬性引用自己時(shí),count自增。當(dāng)為0時(shí),意味可被回收。

缺點(diǎn):

  • 需要頻繁執(zhí)行維護(hù)count的操作
  • 無(wú)法解決循環(huán)依賴(lài)問(wèn)題。比如下圖中的D與E節(jié)點(diǎn),已經(jīng)沒(méi)有其他對(duì)象的內(nèi)部在引用時(shí),應(yīng)該被判定為可回收對(duì)象。但是由于雙方相互引用,形成了循環(huán)依賴(lài),無(wú)法被回收。

可達(dá)性分析(目前主流虛擬機(jī)垃圾回收器采取的算法):

將符合的GC Roots作為初始的存活對(duì)集合,以該集合中的Roots為起點(diǎn),探索所有能夠被Roots引用到的對(duì)象,并加入到Roots集合中,這個(gè)過(guò)程稱(chēng)之為標(biāo)記。未被探索到的對(duì)象即是可回收對(duì)象(死亡的)。

優(yōu)點(diǎn):可以解決引用計(jì)數(shù)算法的循環(huán)依賴(lài)問(wèn)題。從GC Roots出發(fā),無(wú)法探測(cè)到循環(huán)依賴(lài)的對(duì)象,那么就會(huì)進(jìn)行回收。

那么什么樣的對(duì)象可以被作為Root對(duì)象(包括但不限于)

  • 局部變量表中的對(duì)象引用
  • 已被加載的靜態(tài)屬性引用的對(duì)象
  • 常量對(duì)象引用

強(qiáng)-軟-弱-虛引用

有些時(shí)候,我們有這樣一種需求,當(dāng)內(nèi)存足夠時(shí),會(huì)保留一些對(duì)象,方便后續(xù)調(diào)用。當(dāng)內(nèi)存不足時(shí),將這些對(duì)象回收,留出更多的內(nèi)存空間。系統(tǒng)的很多緩存功能符合上述條件。

// 強(qiáng)引用:只要引用可達(dá),就永遠(yuǎn)不會(huì)被回收
Object obj = new Object();
// 軟引用:堆內(nèi)存不夠時(shí)被回收
SoftReference<Object> softReference = new SoftReference<>(obj);
// 弱引用:只要觸發(fā)GC就會(huì)被回收
WeakReference<Object> weakReference = new WeakReference<>(obj);
/**
 * 虛引用:虛引用不會(huì)決定對(duì)象的生命周期,如果一個(gè)對(duì)象持有虛引用,那么和沒(méi)有引用一樣,get永遠(yuǎn)返回null。
 *
 * 需要配合引用隊(duì)列使用,當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)虛引用時(shí),會(huì)將其加入到引用隊(duì)列中。
 *
 * 程序可以根據(jù)虛引用是否入隊(duì),來(lái)了解對(duì)象是否即將被垃圾回收,進(jìn)而執(zhí)行一些響應(yīng)操作。
 */
Object obj2 = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(obj2, referenceQueue);
System.out.println(phantomReference.isEnqueued()); // false
obj2 = null;
System.gc();
Thread.sleep(500);
System.out.println(phantomReference.isEnqueued()); // true

標(biāo)記清除

  • 根據(jù)可達(dá)性分析,標(biāo)記可以回收的對(duì)象
  • 將被標(biāo)記的可回收對(duì)象進(jìn)行回收

內(nèi)存碎片問(wèn)題:造成了不連續(xù)的內(nèi)存碎片。當(dāng)有大對(duì)象需要存儲(chǔ)時(shí),若連續(xù)的碎片空間存儲(chǔ)不下, 難免會(huì)再次觸發(fā)垃圾回收的操作。

標(biāo)記復(fù)制

  • 保留一半的空間,每次只使用一半的空間。
  • 每次GC,根據(jù)可達(dá)性分析,將存活對(duì)象復(fù)制到另一片空間。
  • 釋放本次使用一半空間。

優(yōu)點(diǎn):

  • 只需針對(duì)一半的空間進(jìn)行回收。
  • 避免了內(nèi)存碎片問(wèn)題。
  • 只需要按順序分配內(nèi)存空間即可,實(shí)現(xiàn)簡(jiǎn)單。

缺點(diǎn):

  • 可使用的內(nèi)存空間縮減了一半。
  • 執(zhí)行時(shí)需要STW,導(dǎo)致掛起執(zhí)行的用戶(hù)線程

標(biāo)記整理

標(biāo)記清除的改進(jìn)

  • 根據(jù)可達(dá)性分析,對(duì)可以回收的對(duì)象進(jìn)行標(biāo)記
  • 將未被標(biāo)記的存活對(duì)象移動(dòng)到另一端,然后直接清理掉端邊界以外的內(nèi)存

優(yōu)點(diǎn):解決了標(biāo)記清除的內(nèi)存碎片問(wèn)題

缺點(diǎn):

  • 相比標(biāo)記清除的直接釋放,需要更多的時(shí)間來(lái)完成整理部分的操作
  • 執(zhí)行時(shí)需要STW,導(dǎo)致掛起執(zhí)行的用戶(hù)線程

回收算法的在堆內(nèi)存上的應(yīng)用

新生代

根據(jù)新生代的特點(diǎn),對(duì)象存活率較低,應(yīng)用標(biāo)記復(fù)制算法。分配內(nèi)存空間時(shí),使用Eden區(qū)與一塊Survivor區(qū),GC后將存活的對(duì)象放入到另一塊Survivor區(qū)。如果另一塊Survivor區(qū)不夠存放存活對(duì)象,多數(shù)情況下會(huì)使用老年代進(jìn)行分配擔(dān)保(分配擔(dān)保:將無(wú)法存儲(chǔ)的存活對(duì)象放入其他存儲(chǔ)空間)

循環(huán):

Eden + S0 -> S1 (將Eden 與 S0存活的對(duì)象復(fù)制到S1)

Eden + S1 -> S0

Eden + S0 -> S1

老年代

根據(jù)老年代的特點(diǎn),對(duì)象存活率較高,一般用標(biāo)記-清除,標(biāo)記-整理算法。

到此這篇關(guān)于Java GC垃圾回收算法分析的文章就介紹到這了,更多相關(guān)Java GC垃圾回收內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java開(kāi)發(fā)環(huán)境配置教程(win7 64bit)

    Java開(kāi)發(fā)環(huán)境配置教程(win7 64bit)

    這篇文章主要為大家詳細(xì)介紹了win7 64bit下Java開(kāi)發(fā)環(huán)境的配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java 計(jì)算中位數(shù)的實(shí)現(xiàn)方法

    java 計(jì)算中位數(shù)的實(shí)現(xiàn)方法

    這篇文章主要介紹了java 計(jì)算中位數(shù)的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Spring集成Redis詳解代碼示例

    Spring集成Redis詳解代碼示例

    這篇文章主要介紹了Spring集成Redis詳解代碼示例,介紹了Eclipse工程結(jié)構(gòu),POM依賴(lài),Spring配置,Redis配置信息以及Java代碼等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題

    java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題

    這篇文章主要介紹了java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 淺談Java中OutOfMemoryError問(wèn)題產(chǎn)生原因

    淺談Java中OutOfMemoryError問(wèn)題產(chǎn)生原因

    本文主要介紹了淺談Java中OutOfMemoryError問(wèn)題產(chǎn)生原因,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java實(shí)現(xiàn)合并word文檔的示例代碼

    Java實(shí)現(xiàn)合并word文檔的示例代碼

    在做項(xiàng)目中,經(jīng)常會(huì)遇到一種情況,需要將一個(gè)小word文檔的內(nèi)容插入到一個(gè)大word(主文檔)中。本文就為大家準(zhǔn)備了Java實(shí)現(xiàn)合并word文檔的方法,需要的可以參考一下
    2022-08-08
  • IDEA不編譯除了.java之外的文件的解決辦法(推薦)

    IDEA不編譯除了.java之外的文件的解決辦法(推薦)

    這篇文章主要介紹了IDEA不編譯除了.java之外的文件的解決辦法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 每日六道java新手入門(mén)面試題,通往自由的道路--JVM

    每日六道java新手入門(mén)面試題,通往自由的道路--JVM

    這篇文章主要為大家分享了最有價(jià)值的6道JVM面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對(duì)hashCode方法的設(shè)計(jì)、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Java如何有效避免SQL注入漏洞的方法總結(jié)

    Java如何有效避免SQL注入漏洞的方法總結(jié)

    SQL注入是比較常見(jiàn)的網(wǎng)絡(luò)攻擊方式之一,它不是利用操作系統(tǒng)的BUG來(lái)實(shí)現(xiàn)攻擊,而是針對(duì)程序員編程時(shí)的疏忽,通過(guò)SQL語(yǔ)句,實(shí)現(xiàn)無(wú)帳號(hào)登錄,甚至篡改數(shù)據(jù)庫(kù),這篇文章主要給大家介紹了關(guān)于Java如何避免SQL注入漏洞的兩種方法,需要的朋友可以參考下
    2022-01-01
  • springboot應(yīng)用訪問(wèn)zookeeper的流程

    springboot應(yīng)用訪問(wèn)zookeeper的流程

    這篇文章主要介紹了springboot應(yīng)用訪問(wèn)zookeeper的流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論