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

JVM垃圾回收機(jī)制和垃圾回收器詳細(xì)解說

 更新時(shí)間:2022年07月18日 16:08:05   作者:lose_rose777  
這篇文章主要介紹了JVM垃圾回收機(jī)制和垃圾回收器,為了讓程序員更加專注于代碼的實(shí)現(xiàn),而不用過多的考慮內(nèi)存釋放的問題,所以在Java語(yǔ)言中,有了自動(dòng)的垃圾回收機(jī)制,也是我們常常提及的GC,需要的朋友可以參考下

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

為了讓程序員更加專注于代碼的實(shí)現(xiàn),而不用過多的考慮內(nèi)存釋放的問題,所以在Java語(yǔ)言中,有了自動(dòng)的垃圾回收機(jī)制,也是我們常常提及的GC(Garbage Collection)

有了這個(gè)垃圾回收機(jī)制之后,程序員只需要考慮內(nèi)存的申請(qǐng)即可,內(nèi)存的釋放由系統(tǒng)自動(dòng)識(shí)別完成。在垃圾回收的時(shí)候,不同的對(duì)象引用類型,GC會(huì)采用不同的回收時(shí)機(jī),換句話說自動(dòng)垃圾回收算法就會(huì)變得非常重要,如果因?yàn)樗惴ǖ牟缓侠恚瑢?dǎo)致內(nèi)存資源一直沒有釋放,同樣也可能導(dǎo)致內(nèi)存資源一直沒有被釋放,同樣也可能會(huì)導(dǎo)致內(nèi)存溢出

對(duì)象什么時(shí)候可以被垃圾回收

簡(jiǎn)單用一句話來說:人如果一個(gè)或者多個(gè)對(duì)象沒有任何的引用指向它,那么這個(gè)對(duì)象現(xiàn)在就是垃圾,如果定位成垃圾,那么就有可能被垃圾回收器回收

如果要定位什么是垃圾,有兩種方式來確定,第一個(gè)是引用計(jì)數(shù)法,第二個(gè)是可達(dá)性分析算法

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

一個(gè)對(duì)象被引用一次,在當(dāng)前對(duì)象頭上遞增一次引用次數(shù) ,如果這個(gè)對(duì)象的引用次數(shù)為0,代表這個(gè)對(duì)象可以被回收

String demo = new String("123");

String demo = null;

當(dāng)對(duì)象間出現(xiàn)了循環(huán)引用的話,則引用計(jì)數(shù)法就會(huì)失效,如下圖:

雖然a和b都為null,但是由于a和b存在循環(huán)引用,這樣a和b永遠(yuǎn)都不會(huì)被回收

引用計(jì)數(shù)法的優(yōu)點(diǎn):

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

缺點(diǎn):

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

可達(dá)性分析算法

現(xiàn)在的虛擬機(jī)采用的都是通過可達(dá)性分析算法來確定哪些內(nèi)容是垃圾

首先會(huì)存在一個(gè)根節(jié)點(diǎn)(GC Roots),引出它下面指向的下一個(gè)節(jié)點(diǎn),在以下一個(gè)節(jié)點(diǎn)開始為開始找到它下面的節(jié)點(diǎn),依次往下類推,直到所有節(jié)點(diǎn)全部遍歷完畢。這個(gè)思想類似于算法中的并查集

如上圖,X和Y就是GC Roots無法到達(dá)的節(jié)點(diǎn),那么X和Y就可以被認(rèn)為是垃圾

根對(duì)象是那些肯定不能當(dāng)作垃圾回收的對(duì)象,就可以當(dāng)作根對(duì)象。一般有四種類型可以選做根對(duì)象:

虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象

方法區(qū)中類靜態(tài)屬性引用的對(duì)象

方法區(qū)中常量引用的對(duì)象

本地方法棧中JNI(即一般說的Native方法)引用的對(duì)象(不常用)

JVM垃圾回收算法有哪些

剛剛已經(jīng)講解完了如何定義垃圾,那么定義完成之后的垃圾有一系列的處理算法

標(biāo)記清除算法

標(biāo)記清除算法,是將垃圾回收分為兩個(gè)階段,分別是標(biāo)記和清除

  • 根據(jù)可達(dá)性分析算法得出了垃圾進(jìn)行標(biāo)記
  • 對(duì)這些標(biāo)記為可回收的內(nèi)容進(jìn)行垃圾回收

標(biāo)記清除算法有一定的劣勢(shì):

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

復(fù)制算法

復(fù)制算法的核心就是,將原來的內(nèi)存空間一分為二,每次都是用其中的一塊內(nèi)存。在垃圾回收的時(shí)候,將正在使用的對(duì)象復(fù)制到另一個(gè)內(nèi)存空間中,然后將該內(nèi)存空間清空,交換兩個(gè)內(nèi)存的角色,完成垃圾的

如果內(nèi)存中的垃圾對(duì)象較多,需要復(fù)制的對(duì)象就較少,這種情況下適合使用該 方式并且效率比較高,反之,則不適合

復(fù)制算法的執(zhí)行流程:

  • 將內(nèi)存區(qū)域分成兩個(gè)部分,每次只是操作其中的一個(gè)
  • 當(dāng)進(jìn)行垃圾回收的時(shí)候,將正在使用的內(nèi)存區(qū)域中的存活對(duì)象移動(dòng)到未使用的內(nèi)存區(qū)域。當(dāng)移動(dòng)完成之后,對(duì)這一部分內(nèi)存進(jìn)行一次性清除

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

  • 在垃圾對(duì)象多的情況下,效率較高
  • 清理后,內(nèi)存無碎片

缺點(diǎn):

  • 分配的2塊內(nèi)存空間,在同一個(gè)時(shí)刻,只能使用一半,內(nèi)存使用率較低

標(biāo)記整理算法

標(biāo)記整理算法是在標(biāo)記清除算法的基礎(chǔ)上,做了優(yōu)化和改進(jìn)的算法。和標(biāo)記清除算法一樣,也是從根節(jié)點(diǎn)開始,對(duì)對(duì)象的引用進(jìn)行標(biāo)記,在清理階段,并不是簡(jiǎn)單的直接清理可回收對(duì)象,而是將存活對(duì)象都向內(nèi)存的另一端移動(dòng),讓然后清理邊界以外的垃圾,從而解決了碎片化的問題

標(biāo)記整理算法的執(zhí)行流程:

  • 標(biāo)記垃圾
  • 需要清楚的向右走,不需要清楚的向左走
  • 清除邊界以外的垃圾

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

  • 解決了標(biāo)記清除算法的碎片化的問題
  • 標(biāo)記壓縮算法多了一步,對(duì)象移動(dòng)內(nèi)存位置的步驟,其效率也有有一定的影響
  • 復(fù)制算法標(biāo)記完就復(fù)制,但標(biāo)記整理算法得等把所有存活對(duì)象 都標(biāo)記完畢,再進(jìn)行整理

分代收集算法

在Java8時(shí),堆被分成兩份新生代和老年代(1:2),在Java7的時(shí)候,還存在一個(gè)永久代,Java8將其移動(dòng)到本地內(nèi)存的元空間中

對(duì)于新生代,內(nèi)部被分為三個(gè)區(qū)域:Eden區(qū),兩個(gè)大小完全相同的survivor區(qū)S0(from)和S1(to)(8:1:1)

分代收集算法執(zhí)行流程:

新建的對(duì)象都會(huì)先分配代eden區(qū),當(dāng)eden區(qū)內(nèi)存不足的時(shí)候,會(huì)標(biāo)記eden區(qū)和from區(qū)(現(xiàn)階段還沒有)的存活對(duì)象

將存活下來的對(duì)象采用復(fù)制算法復(fù)制到to中,復(fù)制完畢之后,eden和from內(nèi)存得以釋放

經(jīng)過一段時(shí)間之后,eden區(qū)的內(nèi)存又不足了,標(biāo)記eden區(qū)和to區(qū)存活的對(duì)象,將存貨的對(duì)象復(fù)制到from區(qū)

當(dāng)幸存區(qū)對(duì)象熬過幾次回收(最多15次),晉升到老年代(幸存區(qū)內(nèi)存不足 或大對(duì)象會(huì)導(dǎo)致提前晉升)

MinorGC 、 Mixed GC 、 FullGC 的區(qū)別是什么

  • MinorGC【young GC】發(fā)生在新生代的垃圾回收,暫停時(shí)間短(STW:暫停所有應(yīng)用程序線程,等待垃圾回收的完成)
  • Mixed GC 新生代 + 老年代部分區(qū)域的垃圾回收,G1 收集器特有
  • FullGC 新生代 + 老年代完整垃圾回收,暫停時(shí)間長(zhǎng)(STW),應(yīng)盡力避免

JVM垃圾回收器有哪些

在JVM中,實(shí)現(xiàn)了多種垃圾收集器,包括:

  • 串行垃圾收集器
  • 并行垃圾收集器
  • CMS(并發(fā))垃圾收集器
  • G1垃圾收集器

串行垃圾收集器

Serial和Serial Old串行垃圾收集器,是指使用單線程進(jìn)行垃圾回收,堆內(nèi)存較小,適合個(gè)人電腦

  • Serial作用于新生代,曹勇復(fù)制算法
  • Serial Old作用于年輕代,采用標(biāo)記-整理算法

垃圾回收時(shí),只有一個(gè)線程在工作,并且Java應(yīng)用中所有線程都要暫停(STW),等待垃圾回收的完成

并行垃圾收集器

Parallel New和Parallel Old是一個(gè)并行垃圾回收器,JDK8默認(rèn)使用此垃圾回收器

  • Parallel New作用于新生代,采用復(fù)制算法
  • Parallel Old作用于老年代,采用標(biāo)記-整理算法

垃圾回收時(shí),多個(gè)線程在工作,并且java應(yīng)用中的所有線程都要暫停(STW), 等待垃圾回收的完成

CMS(并發(fā))垃圾收集器

CMS全稱 Concurrent Mark Sweep,是一款并發(fā)的、使用標(biāo)記-清除算法的垃圾回收器,該回收器是針對(duì)老年代垃圾回收的,是一款以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,停頓時(shí)間短,用戶體驗(yàn)就好。其最大特點(diǎn)是在進(jìn)行垃圾回收時(shí),應(yīng)用仍然能正常運(yùn)行

G1垃圾收集器

應(yīng)用于新生代和老年代,在JDK9之后默認(rèn)人使用的G1垃圾收集器。其中劃分了很多個(gè)區(qū)域,每個(gè)區(qū)域都可以充當(dāng)eden,survivor,old,humongous,其中humongous專門為大對(duì)象準(zhǔn)備的。采用的復(fù)制算法,并且注重于響應(yīng)時(shí)間和吞吐量。運(yùn)行時(shí)主要是分為三個(gè)階段:新生代回收、并發(fā)標(biāo)記、混合收集。如果出現(xiàn)并發(fā)失?。椿厥账俣融s不上創(chuàng)建新對(duì)象的速度),就會(huì)觸發(fā)Full GC

下面來詳細(xì)的講解一下年輕代垃圾回收:

初始的時(shí)候,所有的區(qū)域都處于空閑狀態(tài)

創(chuàng)建了一些對(duì)象,挑出一些空閑區(qū)域作為eden區(qū)存儲(chǔ)這些對(duì)象

當(dāng)eden區(qū)需要垃圾回收時(shí),挑出一個(gè)空閑區(qū)域作為survivor,用復(fù)制算法復(fù)制存活對(duì)象,需要暫停用戶線程

隨著時(shí)間流逝,eden區(qū)的內(nèi)存又有不足,將eden區(qū)以及之前幸存區(qū)中存活的對(duì)象,采用復(fù)制算法,復(fù)制到新的幸存區(qū),其中比較老的對(duì)象晉升至老年代

下面來說一下下一個(gè)階段年輕代垃圾回收 + 并發(fā)標(biāo)記:

當(dāng)老年代占用內(nèi)存超過一定的閾值(默認(rèn)是45%)后,觸發(fā)并發(fā)標(biāo)記,這個(gè)時(shí)候無需暫停用戶線程

并發(fā)標(biāo)記之后,會(huì)有重新標(biāo)記階段解決漏標(biāo)問題,此時(shí)需要暫停用戶線程

這些都完成后就知道了老年代有哪些存活對(duì)象,隨后進(jìn)入混合收集階段。此時(shí)不會(huì)對(duì)所有老年代區(qū)域進(jìn)行回收,而是根據(jù)暫停時(shí)間目標(biāo)優(yōu)先回收價(jià)值高 (存活對(duì)象少)的區(qū)域(這也是 Gabage First 名稱的由來)

混合垃圾回收的執(zhí)行流程:

復(fù)制完成,內(nèi)存得到釋放。進(jìn)入到下一輪的新生代回收、并發(fā)標(biāo)記、混合收集

其中H叫做大對(duì)象,如果對(duì)象非常大,就會(huì)開辟一塊連續(xù)的空間存儲(chǔ)巨型對(duì)象

強(qiáng)引用與軟引用與弱引用與虛引用的區(qū)別

強(qiáng)引用:只有所有 GC Roots 對(duì)象都不通過【強(qiáng)引用】引用該對(duì)象,該對(duì)象才能 被垃圾回收

User user = new User()

軟引用:僅有軟引用引用該對(duì)象時(shí),在垃圾回收后,內(nèi)存仍不足時(shí)會(huì)再次出發(fā)垃圾回收

User user = new User();
SoftReference softReference = new SoftReference(user);

弱引用:僅有弱引用引用該對(duì)象時(shí),在垃圾回收時(shí),無論內(nèi)存是否充足,都會(huì)回收弱引用對(duì)象

User user = new User();
WeakReference weakReference = new WeakReference(user);

虛引用:必須配合引用隊(duì)列使用,被引用對(duì)象回收時(shí),會(huì)將虛引用入隊(duì),由Reference Handler線程調(diào)用虛引用相關(guān)方法釋放直接內(nèi)存

User user = new User();
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference(user,queue);

到此這篇關(guān)于JVM垃圾回收機(jī)制和垃圾回收器詳細(xì)解說的文章就介紹到這了,更多相關(guān)JVM垃圾回收內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot解決yml明文密碼問題的方法

    SpringBoot解決yml明文密碼問題的方法

    在現(xiàn)代的軟件開發(fā)中,安全性是一個(gè)重要的考量因素,對(duì)于使用SpringBoot框架開發(fā)的應(yīng)用程序而言,敏感信息如數(shù)據(jù)庫(kù)密碼、API密鑰等通常存儲(chǔ)在YAML配置文件中,而這些文件往往是明文存儲(chǔ),存在安全隱患,所以本文介紹了SpringBoot解決yml明文密碼問題的方法
    2024-07-07
  • Java從控制臺(tái)接受輸入字符的簡(jiǎn)單方法

    Java從控制臺(tái)接受輸入字符的簡(jiǎn)單方法

    這篇文章主要介紹了Java從控制臺(tái)接受輸入字符的簡(jiǎn)單方法,需要的朋友可以參考下
    2014-02-02
  • springboot項(xiàng)目開啟https協(xié)議的項(xiàng)目實(shí)現(xiàn)

    springboot項(xiàng)目開啟https協(xié)議的項(xiàng)目實(shí)現(xiàn)

    本文主要介紹了springboot項(xiàng)目開啟https協(xié)議的項(xiàng)目實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • springboot使用com.github.binarywang包實(shí)現(xiàn)微信網(wǎng)頁(yè)上的支付和退款

    springboot使用com.github.binarywang包實(shí)現(xiàn)微信網(wǎng)頁(yè)上的支付和退款

    最近做項(xiàng)目需要實(shí)現(xiàn)在pc端需要實(shí)現(xiàn)微信的支付,本文主要介紹了springboot使用com.github.binarywang包實(shí)現(xiàn)微信網(wǎng)頁(yè)上的支付和退款,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • Java sha1散列算法原理及代碼實(shí)例

    Java sha1散列算法原理及代碼實(shí)例

    這篇文章主要介紹了Java sha1散列算法原理及代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • maven多個(gè)plugin相同phase的執(zhí)行順序

    maven多個(gè)plugin相同phase的執(zhí)行順序

    這篇文章主要介紹了maven多個(gè)plugin相同phase的執(zhí)行順序,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java實(shí)現(xiàn)定時(shí)任務(wù)的示例代碼

    Java實(shí)現(xiàn)定時(shí)任務(wù)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)定時(shí)任務(wù)的相關(guān)知識(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-11-11
  • 解決Springboot項(xiàng)目打包后的頁(yè)面丟失問題(thymeleaf報(bào)錯(cuò))

    解決Springboot項(xiàng)目打包后的頁(yè)面丟失問題(thymeleaf報(bào)錯(cuò))

    這篇文章主要介紹了解決Springboot項(xiàng)目打包后的頁(yè)面丟失問題(thymeleaf報(bào)錯(cuò)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java如何通過IP解析地理位置

    java如何通過IP解析地理位置

    這篇文章主要介紹了java如何通過IP解析地理位置的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Spring Security實(shí)現(xiàn)微信公眾號(hào)網(wǎng)頁(yè)授權(quán)功能

    Spring Security實(shí)現(xiàn)微信公眾號(hào)網(wǎng)頁(yè)授權(quán)功能

    這篇文章主要介紹了Spring Security中實(shí)現(xiàn)微信網(wǎng)頁(yè)授權(quán),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08

最新評(píng)論