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

Java基礎(chǔ)之垃圾回收機(jī)制詳解

 更新時(shí)間:2021年04月28日 11:12:40   作者:洛白雙雙  
這篇文章主要介紹了Java基礎(chǔ)之垃圾回收機(jī)制詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下

一、GC的作用

進(jìn)行內(nèi)存管理

C語言中的內(nèi)存,申請(qǐng)內(nèi)存之后需要手動(dòng)釋放;一旦忘記釋放,就會(huì)發(fā)生內(nèi)存泄漏!

而Java語言中,申請(qǐng)內(nèi)存后會(huì)由GC來釋放內(nèi)存空間,無需手動(dòng)釋放

GC雖然代替了手動(dòng)釋放的操作,但是它也有局限性:

  •  需要消耗更多的資源;
  • 沒有手動(dòng)釋放那么及時(shí);
  • STW(Stop The World)會(huì)影響程序的執(zhí)行效率

二、GC主要回收哪些內(nèi)存

(1)堆:主要回收堆中的內(nèi)存

(2)方法區(qū):需要回收

(3)棧(包括本地方法棧和JVM虛擬機(jī)棧):不需要回收,棧上的內(nèi)存什么時(shí)候釋放是明確的(線程結(jié)束,棧上的內(nèi)存也就被釋放了;對(duì)應(yīng)的某個(gè)棧幀銷毀[某個(gè)方法執(zhí)行完畢],也會(huì)導(dǎo)致對(duì)應(yīng)的局部變量被釋放)

(4)程序計(jì)數(shù)器:不需要被回收

GC回收內(nèi)存的基本單位:對(duì)象

GC回收對(duì)象的基本思路

(1)標(biāo)記:判斷當(dāng)前對(duì)象的生死,對(duì)象不再被使用為死,則需要回收,反之不需要被回收;

標(biāo)記的方法:

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

記錄當(dāng)前這個(gè)對(duì)象是否有引用指向,有則引用計(jì)數(shù)加1,如果當(dāng)前這個(gè)對(duì)象的引用指向了其他新的對(duì)象,則引用計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)為0的時(shí)候,我們認(rèn)為這個(gè)對(duì)象需要被回收!

缺點(diǎn):無法解決循環(huán)引用問題

下面用一段偽代碼來演示一下循環(huán)引用問題:

class Test{
Test t = null;
}
Test a = new Test();
Test b = new Test();
a.t = b;
b.t = a;
a = null;
b = null;

我們發(fā)現(xiàn),在上述代碼中已經(jīng)沒有辦法使用對(duì)象a和對(duì)象b了,但是它們的引用計(jì)數(shù)不為1.想使用對(duì)象a,就得找到對(duì)象a的引用,但是對(duì)象a的引用又在對(duì)象b當(dāng)中。想使用對(duì)象b,就得找到對(duì)象b 的引用,但是對(duì)象b的引用又在對(duì)象a當(dāng)中。

在這里插入圖片描述

  • 可達(dá)性分析:

代碼中的對(duì)象具有一定的關(guān)聯(lián)關(guān)系,這樣錯(cuò)綜復(fù)雜的關(guān)系,構(gòu)成了一個(gè)"有向圖"??蛇_(dá)性分析也就是遍歷這個(gè)對(duì)象關(guān)系的“有向圖”。如果某個(gè)對(duì)象可以被遍歷到,那么它就是可達(dá)的(非垃圾),那么就是不可達(dá)的(是垃圾)

那么可達(dá)性分析從哪里開始呢?

a)針對(duì)每個(gè)線程的每個(gè)棧幀的局部變量表(線程有很多,每個(gè)線程棧幀也有很多,每個(gè)棧幀也會(huì)有很多個(gè)變量);

b)常量池中引用的對(duì)象;

c)方法區(qū)中靜態(tài)變量引用的對(duì)象;

因?yàn)楸闅v的起點(diǎn)不止一個(gè),而是很多個(gè)起點(diǎn),因此把這些起點(diǎn)也稱之為GCRoot

  • 回收方法區(qū)對(duì)象的規(guī)則:

a)該類的所有實(shí)例已經(jīng)被回收;

b)加載類的ClassLoader也已經(jīng)被回收了;

c)該類對(duì)象沒有在代碼中使用了

同時(shí)具備以上三個(gè)條件,就認(rèn)為該類對(duì)象是可以被回收的

回收的方法:

  • 標(biāo)記-清除【適合老年代】

在這里插入圖片描述

通過上面的圖,我們可以發(fā)現(xiàn),兩個(gè)空閑區(qū)被其他的對(duì)象分隔開了。一旦需要一個(gè)比較大的空間,就會(huì)申請(qǐng)失敗。

標(biāo)記-清除法的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):簡單高效

缺點(diǎn):會(huì)出現(xiàn)內(nèi)存碎片

  • 標(biāo)記-復(fù)制【適合新生代】

在這里插入圖片描述

優(yōu)點(diǎn):解決了內(nèi)存碎片問題,保證回收之后不會(huì)存在碎片(回收后使用的對(duì)象之間是連續(xù)的,空余內(nèi)存之間也是連續(xù)的)

缺點(diǎn):需要一塊額外的空間,如果生存的對(duì)象較多就比較難低效

  • 標(biāo)記-整理【適合老年代】

在這里插入圖片描述

優(yōu)點(diǎn):沒有內(nèi)存碎片問題,也不需要額外的空間

缺點(diǎn):類似于順序表的刪除操作,效率不是很高

三、分代回收

按照對(duì)象的年齡,將堆內(nèi)存分為:新生代(伊甸區(qū)和生存區(qū))、老年代

對(duì)象的年齡不是直接使用時(shí)間來記錄,而是使用對(duì)象活過GC輪次來記錄(GC是按照一定周期來運(yùn)行)

在這里插入圖片描述

一個(gè)對(duì)象的一生:

(1)對(duì)象誕生于新生代的伊甸區(qū)。新產(chǎn)生的對(duì)象的內(nèi)存就是新生代中的內(nèi)存

(2)第一輪GC掃描伊甸區(qū)之后,就會(huì)把大量的對(duì)象回收掉。少數(shù)沒有被回收的對(duì)象,就會(huì)通過標(biāo)記-復(fù)制算法進(jìn)入到生存區(qū)

(3)少數(shù)進(jìn)入生存區(qū)的對(duì)象,再次被GC掃描(對(duì)這些對(duì)象進(jìn)行可達(dá)性分析)。如果發(fā)現(xiàn)該對(duì)象已經(jīng)不可達(dá),也就被銷毀了。沒有被銷毀的對(duì)象,再次通過標(biāo)記-復(fù)制算法,把它拷貝到另一個(gè)生存區(qū)。

(4)對(duì)象在兩個(gè)生存區(qū)中經(jīng)過若干次拷貝,如果還沒有被回收,那么就說明這些個(gè)對(duì)象存活時(shí)間比較久,就拷貝到老年代

(5)老年代的對(duì)象也是要經(jīng)過GC掃描的。由于老年代的對(duì)象生存時(shí)間比較長。因此掃描周期要比新生代的周期要長

相關(guān)術(shù)語:

  • Partical GC:只進(jìn)行一部分內(nèi)存區(qū)域的GC
  • Full GC:針對(duì)整個(gè)內(nèi)存區(qū)域進(jìn)行GC
  • Minor GC:針對(duì)新生代內(nèi)存的GC,執(zhí)行頻繁,速度較快
  • Major GC:針對(duì)老年代的GC,沒那么頻繁。速度較慢,通常由Minor GC 觸發(fā)

四、垃圾回收器

在這里插入圖片描述

垃圾回收器做的兩件事情:標(biāo)記(可達(dá)性分析)+回收(標(biāo)記清除,標(biāo)記復(fù)制,標(biāo)記整理)

  • Serial收集器(給新生代使用,串行回收)【存在STW】

在這里插入圖片描述

采用復(fù)制算法,單線程進(jìn)行標(biāo)記和回收

  • ParNew收集器(新生代收集器,多線程GC)

在這里插入圖片描述

采用復(fù)制算法,多線程進(jìn)行標(biāo)記和回收

  • Parallel scavenge收集器(新生代收集器,并行GC)

設(shè)計(jì)初衷是為了縮短STW時(shí)間,以犧牲吞吐量和新生代空間作為代價(jià)。

相當(dāng)于承諾用戶,在一定時(shí)間內(nèi)就會(huì)完成一次GC。

  • Serial Old收集器(老年代收集器,串行GC)

在這里插入圖片描述

  • Parallel old收集器(老年代收集器,并行GC)

在這里插入圖片描述

使用多線程完成標(biāo)記整理,效率更高,消耗的CPU資源更多

  • CMS垃圾回收器(老年代收集器,并行GC,采用多線程標(biāo)記清除算法)

a)初始標(biāo)記【STW】
只是把和GCRoot相關(guān)的對(duì)象標(biāo)記出來,涉及STW
b)并發(fā)標(biāo)記
執(zhí)行整個(gè)標(biāo)記遍歷的過程(從GCRoot開始,把能訪問的對(duì)象都遍歷)
不需要暫停用戶線程

消耗的時(shí)間相對(duì)比較久,但是可以和用戶線程并發(fā)

注意:當(dāng)進(jìn)行并發(fā)標(biāo)記的時(shí)候,當(dāng)用戶線程也在執(zhí)行,可能導(dǎo)致某個(gè)對(duì)象,剛剛標(biāo)記的時(shí)候不是垃圾,代碼執(zhí)行后,就成了垃圾

c)重新標(biāo)記(CMS remark)【STW】
修正誤差

d)并發(fā)清除
多線程的方式將剛剛的垃圾對(duì)象都清除釋放掉,可以和應(yīng)用程序并發(fā)執(zhí)行

優(yōu)點(diǎn):能夠讓STW時(shí)間盡量短
缺點(diǎn):有內(nèi)存碎片; GC操作和應(yīng)用程序并發(fā)進(jìn)行,消耗CPU資源多;

  • G1回收器(Java11開始默認(rèn)使用)

既可以回收新生代,也可以回收老年代

在這里插入圖片描述

每個(gè)矩形稱為一個(gè)region
E表示伊甸區(qū)
S表示生存區(qū)
T表示老年代
H表示存放大對(duì)象的區(qū)域
以region為單位進(jìn)行回收,回收粒度更精細(xì)
針對(duì)新生區(qū)的region同樣適用復(fù)制算法
針對(duì)老年代的回收類似于CMS
a)初始標(biāo)記【STW】:只去找和GRoot直接相連的對(duì)象
b)并發(fā)標(biāo)記:和應(yīng)用程序并發(fā)執(zhí)行,進(jìn)行可達(dá)性分析,遍歷所有對(duì)象。如果發(fā)現(xiàn)某個(gè)老年代region中已經(jīng)沒有存活對(duì)象,就直接回收
c)最終標(biāo)記:修正第二步產(chǎn)生的誤差
d)篩選回收:挑選出對(duì)象存活率低的region進(jìn)行回收

五、總結(jié)

在這里插入圖片描述

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

相關(guān)文章

  • Java實(shí)現(xiàn)解數(shù)獨(dú)的小程序

    Java實(shí)現(xiàn)解數(shù)獨(dú)的小程序

    最近在學(xué)習(xí)Java,然后上個(gè)月迷上了九宮格數(shù)獨(dú),玩了幾天,覺得實(shí)在有趣,就想著能不能用編程來解決,于是就自己寫了個(gè),還真解決了。下面這篇文章就給大家主要介紹了Java實(shí)現(xiàn)解數(shù)獨(dú)的小程序,需要的朋友可以參考借鑒。
    2017-01-01
  • Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析

    這篇文章主要介紹了Java Netty實(shí)現(xiàn)心跳機(jī)制過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Springboot整合quartz實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)實(shí)例

    Springboot整合quartz實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)實(shí)例

    這篇文章主要介紹了Springboot整合quartz實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)代碼實(shí)例,Quartz?是一款功能強(qiáng)大的開源任務(wù)調(diào)度框架,幾乎可以集成到任何?Java?應(yīng)用程序中,Quartz?可用于創(chuàng)建簡單或復(fù)雜的任務(wù)調(diào)度,用以執(zhí)行數(shù)以萬計(jì)的任務(wù),需要的朋友可以參考下
    2023-08-08
  • 手把手教你實(shí)現(xiàn)Java第三方應(yīng)用登錄

    手把手教你實(shí)現(xiàn)Java第三方應(yīng)用登錄

    本文主要介紹了手把手教你實(shí)現(xiàn)Java第三方應(yīng)用登錄,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java中的OkHttp使用教程

    Java中的OkHttp使用教程

    OkHttp是目前非常火的網(wǎng)絡(luò)庫,OKHttp與HttpClient類似,也是一個(gè)Http客戶端,提供了對(duì)?HTTP/2?和?SPDY?的支持,并提供了連接池,GZIP?壓縮和?HTTP?響應(yīng)緩存功能,本文重點(diǎn)給大家介紹Java?OkHttp使用,感興趣的朋友一起看看吧
    2022-04-04
  • 詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比

    詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比

    這篇文章主要介紹了詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Java中零拷貝和深拷貝的原理及實(shí)現(xiàn)探究(代碼示例)

    Java中零拷貝和深拷貝的原理及實(shí)現(xiàn)探究(代碼示例)

    深拷貝和零拷貝是兩個(gè)在 Java 中廣泛使用的概念,它們分別用于對(duì)象復(fù)制和數(shù)據(jù)傳輸優(yōu)化,下面將詳細(xì)介紹這兩個(gè)概念的原理,并給出相應(yīng)的 Java 代碼示例,感興趣的朋友一起看看吧
    2023-12-12
  • 詳解SpringBoot的三種緩存技術(shù)(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)

    詳解SpringBoot的三種緩存技術(shù)(Spring Cache、Layering Cache 框架、Alibaba J

    這篇文章主要介紹了SpringBoot的三種緩存技術(shù),幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • 通過實(shí)例了解Java jdk和jre的區(qū)別

    通過實(shí)例了解Java jdk和jre的區(qū)別

    這篇文章主要介紹了通過實(shí)例了解Java jdk和jre的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java調(diào)用Pytorch實(shí)現(xiàn)以圖搜圖功能

    Java調(diào)用Pytorch實(shí)現(xiàn)以圖搜圖功能

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Pytorch實(shí)現(xiàn)以圖搜圖功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06

最新評(píng)論