<del id="d4fwx"><form id="d4fwx"></form></del>
      <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

            <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
          • java代碼可達(dá)性分析,可達(dá)性模型分析

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

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

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

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

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

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

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

            ? ? ? ? ? ? ?

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

            引用分類:

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

            軟引用;notmust

            弱引用;

            虛引用;

            數(shù)組、對象

            類似:Object obj = new Object()

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

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

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

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

            非必需對象

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

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

            無法通過虛引用來去的一個(gè)對象實(shí)例。

            對象存活判定算法:

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

            思路:

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

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

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

            缺點(diǎn):

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

            思路:

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

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

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

            應(yīng)用:

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

            Java中,可作為GC Roots的對象包括:

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

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

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

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

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

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

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

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

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

            收集器?

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

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

            jdk8:垃圾回收算法

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

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

            解釋

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

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

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

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

            缺陷

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

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

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

            解決辦法

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

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

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

            解釋

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

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

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

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

            3. Java語言中的GC Roots

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

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

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

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

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

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

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

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

            基本思路:

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

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

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

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

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

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

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

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

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

            就是不能解決循環(huán)依賴的問題。

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

            接下來面試官可能會問:

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

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

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

            (這這些問題,文末會給出解答)

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

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

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

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

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

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

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

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

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

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

            白色:表示對象未被垃圾回收器訪問過 。

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

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

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

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

            如下圖所示:

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

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

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

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

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

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

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

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

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

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

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

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

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

            Thread - 活著的線程

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

            JNI Local、JNI Global

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

            在Java語言里,可以作為GC Roots對象的包括如下幾種:

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

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

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

            第一次標(biāo)記

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

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

            第二次標(biāo)記

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

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

            (未完待續(xù))

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

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

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

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

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

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

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

            廣告

            聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

            綿陽服務(wù)器托管

              <del id="d4fwx"><form id="d4fwx"></form></del>
              <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

                    <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
                  • 男操女逼射逼心国产中字传媒视频 | 国产成人综合欧美精品久久 | 国产精品秘 久久久久久奇米影视 | 免费黄色视频观看 | 99热日韩|