bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

java代碼可達(dá)性分析,可達(dá)性模型分析

可達(dá)性分析算法及4種引用說(shuō)明

哪些對(duì)象可以被回收 徹底失去引用的對(duì)象? GC roots 可達(dá)性分析算法 可以判斷 沒(méi)有引用鏈的就可以被回收。這算第一次標(biāo)記。第二次標(biāo)記成功后會(huì)被回收。

馬龍ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書(shū)合作)期待與您的合作!

對(duì)象在內(nèi)存中的狀態(tài):

可達(dá)狀態(tài):

可恢復(fù)狀態(tài):

不可達(dá)狀態(tài):

? ? ? ? ? ? ?

判斷對(duì)象是否存活都與引用有關(guān),下面介紹一下引用的分類(lèi):

引用分類(lèi):

強(qiáng)引用;Object obj = new Object()

軟引用;notmust

弱引用;

虛引用;

數(shù)組、對(duì)象

類(lèi)似:Object obj = new Object()

只要存在強(qiáng)引用,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象

描述一些還有用但并非必須的對(duì)象。在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前,將會(huì)把這些對(duì)象列入回收范圍之中進(jìn)行第二次回收。如果這次回收之后還沒(méi)有足夠的內(nèi)存——拋出內(nèi)存異常

內(nèi)存充足,不會(huì)回收

內(nèi)存不足,回收

非必需對(duì)象

垃圾回收機(jī)制運(yùn)行時(shí),不管內(nèi)存充足與否,都會(huì)回收

不能單獨(dú)存在,必須和引用隊(duì)列聯(lián)合使用。

無(wú)法通過(guò)虛引用來(lái)去的一個(gè)對(duì)象實(shí)例。

對(duì)象存活判定算法:

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

思路:

給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)一個(gè)地方引用它時(shí),計(jì)數(shù)器加1;

當(dāng)引用失效時(shí),計(jì)數(shù)器值就減1;

任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不能再被使用的。

缺點(diǎn):

很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。導(dǎo)致他們的引用計(jì)數(shù)都不為0,于是引用計(jì)數(shù)算法無(wú)法通知GC收集器回收他們。

思路:

通過(guò)一系列的成為“GC Roots”的對(duì)象作為起始點(diǎn),

從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑成為引用鏈(Reference Chain),

當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí),則證明此對(duì)象是不可用的。

應(yīng)用:

現(xiàn)在主流的商用程序語(yǔ)言(java,C#)都是通過(guò)可達(dá)性分析來(lái)判斷對(duì)象是否存活的。

Java中,可作為GC Roots的對(duì)象包括:

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

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

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

本地方法棧中JNI(即Native方法)引用的對(duì)象;

對(duì)象死亡(被回收)前的最后一次掙扎

??即使在可達(dá)性分析算法中不可達(dá)的對(duì)象,也并非是“非死不可”,這時(shí)候它們暫時(shí)處于“緩刑”階段,要真正宣告一個(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過(guò)程。

??第一次標(biāo)記:如果對(duì)象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒(méi)有與GC Roots相連接的引用鏈,那它將會(huì)被第一次標(biāo)記;

??第二次標(biāo)記:第一次標(biāo)記后接著會(huì)進(jìn)行一次篩選,篩選的條件是此對(duì)象是否有必要執(zhí)行finalize()方法。在finalize()方法中沒(méi)有重新與引用鏈建立關(guān)聯(lián)關(guān)系的,將被進(jìn)行第二次標(biāo)記。

??第二次標(biāo)記成功的對(duì)象將真的會(huì)被回收,如果對(duì)象在finalize()方法中重新與引用鏈建立了關(guān)聯(lián)關(guān)系,那么將會(huì)逃離本次回收,繼續(xù)存活。

收集器?

淺談CMS垃圾收集器與G1收集器

Java之美[從菜鳥(niǎo)到高手演變]之JVM內(nèi)存管理及垃圾回收

jdk8:垃圾回收算法

怎么驗(yàn)證java的gc是否會(huì)回收了某個(gè)不用的對(duì)象了。我有段代碼有性能問(wèn)題,需要調(diào)優(yōu),想知道怎么看

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

解釋

系統(tǒng)給每個(gè)對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用這個(gè)對(duì)象的時(shí)候,計(jì)數(shù)器就加1,當(dāng)引用失效的時(shí)候,計(jì)數(shù)器就減1,在任何一個(gè)時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能被使用的對(duì)象,因?yàn)闆](méi)有任何地方持有這個(gè)引用,這時(shí)這個(gè)對(duì)象就被視為內(nèi)存垃圾,等待被虛擬機(jī)回收

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

客觀的說(shuō),引用計(jì)數(shù)器算法,他的實(shí)現(xiàn)很簡(jiǎn)單,判定的效率很高,在大部分情況下這都是相當(dāng)不錯(cuò)的算法

其實(shí),很多案例中都使用了這種算法,比如 IOS 的Object-C , 微軟的COM技術(shù)(用于給window開(kāi)發(fā)驅(qū)動(dòng),.net里面的技術(shù)幾乎都是建立在COM上的),Python語(yǔ)言等.

缺陷

無(wú)法解決循環(huán)引用的問(wèn)題.

這就好像是懸崖邊的人采集草藥的人, 想要活下去就必須要有一根繩子綁在懸崖上. 如果有兩個(gè)人, 甲的手拉著懸崖, 乙的手拉著甲, 那么這兩個(gè)人都能活, 但是, 如果甲的手拉著乙, 乙的手也拉著甲, 雖然這兩個(gè)人都認(rèn)為自己被別人拉著, 但是一樣會(huì)掉下懸崖.

比如說(shuō) A對(duì)象的一個(gè)屬性引用B,B對(duì)象的一個(gè)屬性同時(shí)引用A A.b = B() B.a = A(); 這個(gè)A,B對(duì)象的計(jì)數(shù)器都是1,可是,如果沒(méi)有其他任何地方引用A,B對(duì)象的時(shí)候,A,B對(duì)象其實(shí)在系統(tǒng)中是無(wú)法發(fā)揮任何作用的,既然無(wú)法發(fā)揮作用,那就應(yīng)該被視作內(nèi)存垃圾予以清理掉,可是因?yàn)榇藭r(shí)A,B的計(jì)數(shù)器的值都是1,虛擬機(jī)就無(wú)法回收A,B對(duì)象,這樣就會(huì)造成內(nèi)存浪費(fèi),這在計(jì)算機(jī)系統(tǒng)中是不可容忍的.

解決辦法

在語(yǔ)言層面處理, 例如Object-C 就使用強(qiáng)弱引用類(lèi)型來(lái)解決問(wèn)題.強(qiáng)引用計(jì)數(shù)器加1 ,弱引用不增加

Java中也有強(qiáng)弱引用

2. 可達(dá)性分析算法

解釋

這種算法通過(guò)一系列成為 "GC Roots " 的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索所有走過(guò)的路徑成為引用鏈(Reference Chain) , 當(dāng)一個(gè)對(duì)象GC Roots沒(méi)有任何引用鏈相連(用圖論的話來(lái)說(shuō)就是從GC Roots到這個(gè)對(duì)象不可達(dá)),則證明此對(duì)象是不可用的

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

這個(gè)算法可以輕松的解決循環(huán)引用的問(wèn)題

大部分的主流java虛擬機(jī)使用的都是這種算法

3. Java語(yǔ)言中的GC Roots

在虛擬機(jī)棧(其實(shí)是棧幀中的本地變量表)中引用的對(duì)象

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

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

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

可達(dá)性分析起始點(diǎn)未定位原因

相對(duì)于引用計(jì)數(shù)算法而言,可達(dá)性分析算法不僅同樣具備實(shí)現(xiàn)簡(jiǎn)單和執(zhí)行高效等特點(diǎn),更重要的是該算法可以有效解決引用計(jì)數(shù)算法中循環(huán)引用的問(wèn)題,防止內(nèi)存泄漏的發(fā)生

java選擇的就是可達(dá)性分析算法,這種類(lèi)型的垃圾收集通常也叫做追蹤性垃圾收集

所謂GC ROOTS 根集合就是一組必須活躍的引用

基本思路:

1.可達(dá)性分析算法是以根對(duì)象集合(GC Roots)為起始點(diǎn),按照從上至下的方式搜索被根對(duì)象集合所連接的目標(biāo)對(duì)象是否可達(dá)

2.使用可達(dá)性分析算法后,內(nèi)存中的存活對(duì)象都會(huì)被根對(duì)象集合直接或間接連接著,搜索所走過(guò)的路徑稱(chēng)為引用鏈

3.如果目標(biāo)對(duì)象沒(méi)有任何引用鏈項(xiàng)鏈,則是不可達(dá)的,就意味著該對(duì)象已經(jīng)死亡,可以標(biāo)記為垃圾對(duì)象

4.在可達(dá)性分析算法中,只有能夠被根對(duì)象集合直接或者間接連接的對(duì)象才是存活對(duì)象

JVM并發(fā)的可達(dá)性分析

j當(dāng)面試扯到j(luò)vm這一部分的時(shí)候,面試官大概率會(huì)問(wèn)你 jvm怎么判斷哪些對(duì)象應(yīng)該回收呢 ?

你會(huì)脫口而出 引用計(jì)數(shù)算法 和 可達(dá)性分析算法 。

引用計(jì)數(shù)法: 在對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)一個(gè)地方引用它時(shí),計(jì)數(shù)器就加一;當(dāng)引用失效時(shí),計(jì)數(shù)器值就減一;任何時(shí)刻計(jì)數(shù)器為零的對(duì)象就是不可能再被使用的。

但是這樣的算法有一個(gè)問(wèn)題?

就是不能解決循環(huán)依賴(lài)的問(wèn)題。

可達(dá)性分析算法的思路 就是通過(guò)一系列的“GC Roots”,也就是根對(duì)象作為起始節(jié)點(diǎn),從根節(jié)點(diǎn)開(kāi)始,根據(jù)引用關(guān)系向下搜索,搜索過(guò)程所走過(guò)的路徑稱(chēng)為引用鏈,如果某個(gè)對(duì)象到GC Roots間沒(méi)有任何引用鏈相連。就是說(shuō)從GC Roots到這個(gè)對(duì)象不可達(dá)時(shí),則證明此對(duì)象是不可能再被使用的,是可以被回收的對(duì)象。

接下來(lái)面試官可能會(huì)問(wèn):

你剛剛談到了根節(jié)點(diǎn),那你知道哪些對(duì)象可以作為根對(duì)象嗎?

你剛剛談到了引用,那你知道java里面有哪幾種引用嗎?

你剛剛談到了可達(dá)性分析算法,那如果在該算法中被判定不可達(dá)對(duì)象,是不是一定會(huì)被回收呢?

(這這些問(wèn)題,文末會(huì)給出解答)

這些問(wèn)題太常規(guī)了,本文要講一些不那么常見(jiàn)的: 并發(fā)標(biāo)記 , 浮動(dòng)垃圾 。

CMS和G1都有一個(gè)并發(fā)標(biāo)記的過(guò)程,并發(fā)標(biāo)記要解決什么問(wèn)題?帶來(lái)了什么問(wèn)題?怎么解決這些問(wèn)題呢?

剛剛我們談到的可達(dá)性分析算法是需要一個(gè)理論上的前提的: 該算法的全過(guò)程都需要基于一個(gè)能保障一致性的快照才能夠分析,這意味著必須全程凍結(jié)用戶(hù)線程的運(yùn)行。 而為了不凍結(jié)用戶(hù)線程的運(yùn)行,那我們就需要讓垃圾回收線程和用戶(hù)線程同時(shí)運(yùn)行。

那我們先假設(shè)不并發(fā)標(biāo)記,即只有垃圾回收線程在運(yùn)行的流程是怎樣的:

第一步:找到根節(jié)點(diǎn),也就是我們常說(shuō)的 根節(jié)點(diǎn)枚舉 。

在這個(gè)過(guò)程中,由于GC Roots是遠(yuǎn)遠(yuǎn)小與整個(gè)java堆中的全部對(duì)象,而且在OopMap此類(lèi)優(yōu)化技巧的加持下,它帶來(lái)的停頓是非常短暫且固定的, 可以理解為不會(huì)隨著堆里的對(duì)象的增加而增加 ,如圖:

首先我們要搞清楚一個(gè)問(wèn)題: 為什么遍歷對(duì)象圖的時(shí)候必須在一個(gè)能保證一致性的快照中?

為了說(shuō)明這個(gè)問(wèn)題,我們引入 “三色標(biāo)記” 方法。

什么是“三色標(biāo)記”?

在遍歷對(duì)象圖的過(guò)程中,把訪問(wèn)的對(duì)象按照"是否訪問(wèn)過(guò)"這個(gè)條件標(biāo)記成以下三種顏色:

白色:表示對(duì)象未被垃圾回收器訪問(wèn)過(guò) 。

顯然可達(dá)性分析剛開(kāi)始的時(shí)候,所有的對(duì)象都是白色,若在結(jié)束的時(shí)候,仍是白色的對(duì)象,即代表不可達(dá)。

黑色:表示已經(jīng)被垃圾回收器訪問(wèn)過(guò),且這個(gè)對(duì)象的所有引用都已經(jīng)掃描過(guò)

黑色的對(duì)象代表已經(jīng)掃描過(guò),它是安全存活的,如果有其它的對(duì)象引用指向了黑色對(duì)象,無(wú)須重新掃描一遍。黑色對(duì)象不可能直接(不經(jīng)過(guò)灰色對(duì)象)指向某個(gè)白色對(duì)象。

灰色:表示已經(jīng)被垃圾回收器掃描過(guò),但這個(gè)對(duì)象至少存在一個(gè)引用還沒(méi)有被掃描 。

如下圖所示:

我們先看一下正常標(biāo)記的過(guò)程:

首先是初始狀態(tài),很簡(jiǎn)單,只有GC Roots是黑色的。同時(shí)需要注意下面的圖片的箭頭方向,代表的是有向的,比如其中的一條引用鏈?zhǔn)牵?/p>

跟節(jié)點(diǎn)-5-6-7-8-11-10

如果在標(biāo)記的過(guò)程中,用戶(hù)線程修改了引用關(guān)系,就會(huì)出現(xiàn)下面的情況:

有一個(gè)大佬叫Wilson,他在1994年在理論上證明了, 只有同時(shí)滿足以下兩個(gè)條件時(shí) ,會(huì)產(chǎn)生“對(duì)象消失”的問(wèn)題,原來(lái)應(yīng)該是黑色的對(duì)象被標(biāo)記成了白色。

增量更新要破壞的是第一個(gè)條件(賦值器插入了一條或者多條從黑色對(duì)象到白色對(duì)象的新引用),當(dāng)黑色對(duì)象插入新的指向白色對(duì)象的引用關(guān)系時(shí),就將這個(gè)新插入的引用 記錄下來(lái) ,等并發(fā)掃描結(jié)束之后,再以這些記錄過(guò)的引用關(guān)系中的黑色對(duì)象為根, 重新掃描一次 。

可以簡(jiǎn)化的理解為: 黑色對(duì)象一旦插入了指向白色對(duì)象的引用之后,它就變回了灰色對(duì)象 。

下面的圖就是一次并發(fā)掃描結(jié)束之后,記錄了黑色對(duì)象5新指向了白色對(duì)象9:

原始快照要破壞的是第二個(gè)條件(賦值器刪除了全部從灰色對(duì)象到該白色對(duì)象的直接或間接引用),當(dāng)灰色對(duì)象要?jiǎng)h除指向白色對(duì)象的引用關(guān)系時(shí),就將這個(gè)要?jiǎng)h除的引用記錄下來(lái),在并發(fā)掃描結(jié)束之后,再以這些記錄過(guò)的引用關(guān)系中的灰色對(duì)象為根,重新掃描一次。

可以簡(jiǎn)化理解為:無(wú)論引用關(guān)系刪除與否,都會(huì)按照剛剛開(kāi)始掃描那一刻的對(duì)象圖快照開(kāi)進(jìn)行搜索。

接下來(lái)回答一下,上面遺留的幾個(gè)問(wèn)題:

GC管理的主要區(qū)域是Java堆,一般情況下只針對(duì)堆進(jìn)行垃圾回收。方法區(qū)、棧和本地方法區(qū)不被GC所管理,因而選擇這些區(qū)域內(nèi)的對(duì)象作為GC Roots,被GC Roots引用的對(duì)象不被GC回收。

Class - 由系統(tǒng)類(lèi)加載器(system class loader)加載的對(duì)象,這些類(lèi)是不能夠被回收的,他們可以以靜態(tài)字段的方式保存持有其它對(duì)象。

Thread - 活著的線程

Stack Local - Java方法的local變量或者參數(shù)

JNI Local、JNI Global

Monitor Used - 用于同步的監(jiān)控對(duì)象

在Java語(yǔ)言里,可以作為GC Roots對(duì)象的包括如下幾種:

你知道java里面有哪幾種引用嗎?

在可達(dá)性分析算法判定為不可達(dá)的對(duì)象,是不是一定會(huì)被回收呢?

即使在可達(dá)性算法中不可達(dá)的對(duì)象也不一定是非死不可的,這時(shí)候它們暫時(shí)處于“緩刑”階段,要真正宣告它的死亡還需要經(jīng)歷兩次的標(biāo)記階段。

第一次標(biāo)記

在對(duì)象可達(dá)性算法不可達(dá)時(shí),進(jìn)行第一次標(biāo)記,并且進(jìn)行一次篩選,篩選的條件是此對(duì)象是否有必要執(zhí)行finalize()方法。當(dāng)對(duì)象沒(méi)有覆蓋finalize方法或者該方法被虛擬機(jī)調(diào)用過(guò),虛擬機(jī)將這兩種情況視為“沒(méi)有必要去執(zhí)行”,回收。

如果該對(duì)象被判定為有必要執(zhí)行finalize()方法,那么這個(gè)對(duì)象會(huì)被放置到一個(gè)叫做F-Queue的隊(duì)列中,并在稍后由一個(gè)虛擬機(jī)自動(dòng)建立的、低優(yōu)先級(jí)的Finalize線程去執(zhí)行它。這里所謂的執(zhí)行就是去觸發(fā)該方法,但是并不會(huì)承諾等待它執(zhí)行結(jié)束,這樣做的原因是,如果對(duì)象在finalize()方法中執(zhí)行緩慢,或者發(fā)生死循環(huán),將會(huì)導(dǎo)致整個(gè)隊(duì)列中的對(duì)象處于等待之中。

第二次標(biāo)記

finalize()方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì),稍后GC將對(duì)F-Queue中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記,如果對(duì)象要在finalize()中拯救自己——只要重新與引用鏈上的一個(gè)對(duì)象重新建立關(guān)聯(lián)即可,比如將自己(this關(guān)鍵字)賦值給某個(gè)類(lèi)變量或者成員變量,那么在第二次標(biāo)記的時(shí)候就會(huì)被移除“即將回收”的集合;如果對(duì)象這時(shí)候還沒(méi)有逃脫,那么就會(huì)被真的回收了。

注意:第二次自救失敗是因?yàn)槿魏我粋€(gè)對(duì)象的finalize()方法只能執(zhí)行一次,如果第二次回收,就不會(huì)執(zhí)行finalize方法了!

(未完待續(xù))

Java可達(dá)性分析算法會(huì)不會(huì)出現(xiàn)循環(huán)引用問(wèn)題

GC Root在對(duì)象圖之外,是特別定義的“起點(diǎn)”,不可能被對(duì)象圖內(nèi)的對(duì)象所引用。

一個(gè)常見(jiàn)的誤解是以為GC Root是一組對(duì)象。

實(shí)際情況是GC Root通常是一組特別管理的指針,這些指針是tracing GC的trace的起點(diǎn)。它們不是對(duì)象圖里的對(duì)象,對(duì)象也不可能引用到這些“外部”的指針,所以題主想像的情況無(wú)法成立。

另外,tracing GC能正確處理循環(huán)引用,保證每個(gè)活對(duì)象只會(huì)被訪問(wèn)一次就能確定其存活性。對(duì)象圖里是否存在循環(huán)引用,tracing GC都能正確判斷對(duì)象的存活與否。

新聞標(biāo)題:java代碼可達(dá)性分析,可達(dá)性模型分析
當(dāng)前鏈接:http://vcdvsql.cn/article16/hedcgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)外貿(mào)建站網(wǎng)站改版網(wǎng)頁(yè)設(shè)計(jì)公司自適應(yīng)網(wǎng)站靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管