在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    「深入理解java虛擬機(jī)」 – JVM垃圾回收算法

    「深入理解java虛擬機(jī)」 - JVM垃圾回收算法

    文章目錄

    對(duì)象是否存活?

    垃圾收集器在對(duì)堆進(jìn)行回收前,第一件事情就是 是要確定這些對(duì)象之中哪些還“存活”著,哪些已經(jīng)“死去”。

    判斷對(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ì)象就是不可能再被使用的。

    引用計(jì)數(shù)法原理簡(jiǎn)單,判定效率也很高,但單純的引用計(jì)數(shù)就很難解決 對(duì)象之間相互循環(huán)引用的問題 。

    例如,存在兩個(gè)對(duì)象象 objA 和 objB ,他們都有字段instance,令 objA.instance=objB;objB.instance=objA 。除此之外,這兩個(gè)對(duì)象再無任何引用,實(shí)際上這兩個(gè)對(duì)象已經(jīng) 經(jīng)不可能再被訪問,但是它們因?yàn)榛ハ嘁弥鴮?duì)方,導(dǎo)致它們的引用計(jì)數(shù)都不為零,引用計(jì)數(shù)算法也就無法回收它們。

    可達(dá)性分析法

    通過 一系列稱為“GC Roots”的根對(duì)象作為起始節(jié)點(diǎn)集,從這些節(jié)點(diǎn)開始,根據(jù)引用關(guān)系向下搜索,搜索過 程所走過的路徑稱為“引用鏈”(Reference Chain),如果某個(gè)對(duì)象到GC Roots間沒有任何引用鏈相連, 或者用圖論的話來說就是從GC Roots到這個(gè)對(duì)象不可達(dá)時(shí),則證明此對(duì)象是不可能再被使用的。

    固定可作為GC Roots的對(duì)象包括以下幾種:

    • 方法區(qū)中類靜態(tài)屬性引用的對(duì)象;
    • 在方法區(qū)中常量引用的對(duì)象;
    • 在本地方法棧中(即Native方法)引用的對(duì)象;
    • 所有被同步鎖(synchronized關(guān)鍵字)持有的對(duì)象;
    • 反映Java虛擬機(jī)內(nèi)部情況的JMXBean、JVMTI中注冊(cè)的回調(diào)、本地代碼緩存等。

    強(qiáng)、軟、弱、虛

  • 強(qiáng)引用程序代碼之中普遍存在的引用賦值,例如 Object obj=new Object() 。無論任何情況下,只要強(qiáng)引用關(guān)系還存在,垃圾收集器就永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象。
  • 軟引用描述一些 還有用,但非必須的對(duì)象 。只被軟引用關(guān)聯(lián)著的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常前,會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第二次回收,如果這次回收還沒有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常。
  • 弱引用描述那些 非必須對(duì)象 ,但是它的強(qiáng)度比軟引用更弱一些,被弱引用關(guān)聯(lián)的對(duì)象只 能生存到下一次垃圾收集發(fā)生為止。 當(dāng)垃圾收集器開始工作,無論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉只被引用關(guān)聯(lián)的對(duì)象。
  • 虛引用也稱為“幽靈引用”或者“幻影引用”,它是最弱的一種引用關(guān)系。一個(gè)對(duì)象是否有序引用的意思 存在,完全 不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無法通過虛引用來取得一個(gè)對(duì)象實(shí)例。 為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的只是為了能在這個(gè) 對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知 。
  • finalize()

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

  • 如果對(duì)象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒有與GC Roots相連接的引用鏈,那它將會(huì)被第一次標(biāo)記,隨后進(jìn)行一次篩選,篩選的條件是此對(duì)象是否有必要執(zhí)行finalize()方法( 對(duì)象中覆蓋finalize()方法,并且未被虛擬機(jī)調(diào)用 )。如果這個(gè)對(duì)象被判定為確有必要執(zhí)行finalize()方法,那么該對(duì)象將會(huì)被放置在一個(gè)名為F-Queue的 隊(duì)列之中,并在稍后由一條由虛擬機(jī)自動(dòng)建立的、低調(diào)度優(yōu)先級(jí)的Finalizer線程去執(zhí)行它們的finalize() 方法。
  • finalize()方法是對(duì) 象逃脫死亡命運(yùn)的最后一次機(jī)會(huì),稍后收集器將對(duì)F-Queue中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記,如果 對(duì)象在finalize()中與引用鏈上的任何一個(gè)對(duì)象建立了關(guān)聯(lián) ,它仍然可以存活。
  • 【注】

    • 任何一個(gè)對(duì)象的finalize()方法都只會(huì)被系統(tǒng)自動(dòng)調(diào)用一次,如果對(duì)象面臨 下一次回收,它的finalize()方法不會(huì)被再次執(zhí)行;
    • 虛擬機(jī)會(huì)觸發(fā)finalize方法開始運(yùn)行,但并不承諾一定會(huì)等待它運(yùn)行結(jié)束。

    垃圾收集算法

    分代收集理論

    分代收集指的是:垃圾收集器應(yīng)該將Java堆劃分 除去不同的區(qū)域,然后將回收對(duì)象依據(jù)其年齡(年齡即 對(duì)象熬過垃圾收集過程的次數(shù) )分配到不同地區(qū) 域之中存儲(chǔ)。

    據(jù)此,一般至少將把Java堆劃分為 新生代 (Young Generation)和 老年代 (Old Generation)兩個(gè)區(qū)域。在新生代中,每次都是垃圾收集 時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,而每次回收后存活的少量對(duì)象,將會(huì)逐步晉升到老年代中存放。

    三個(gè)假說:

  • 弱分代假說:絕大多數(shù)對(duì)象都是朝生夕滅的。
  • 強(qiáng)分代假說:熬過越多次垃圾收集過程的對(duì)象就越難以消 亡。
  • 跨代引用假說:跨代引用相對(duì)于同代引用來說僅占極少數(shù)。
  • 標(biāo)記—清除算法

    標(biāo)記-清除算法分為“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所有需要回復(fù) 收的對(duì)象,在標(biāo)記完成后,統(tǒng)一回收掉所有被標(biāo)記的對(duì)象,也可以反過來,標(biāo)記存活的對(duì)象,統(tǒng)一回收所有未被標(biāo)記的對(duì)象。

    缺點(diǎn):

    • 執(zhí)行效率不穩(wěn)定 ,如果Java堆中包含大量對(duì) 象,而且其中大部分是需要被回收的,這時(shí)必須進(jìn)行大量標(biāo)記和清除的動(dòng)作,導(dǎo)致標(biāo)記和清除兩個(gè)過程 程的執(zhí)行效率都隨對(duì)象數(shù)量增長(zhǎng)而降低;
    • 內(nèi)存空間的碎片化問題 ,標(biāo)記、清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致當(dāng)以后在程序運(yùn)行過程中需要分配較大對(duì)象時(shí)無法找 到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。

    標(biāo)記-復(fù)制算法

    標(biāo)記-復(fù)制算法:將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對(duì)象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。

    如果內(nèi)存中多數(shù)對(duì)象都是存 活的,這種算法將會(huì)產(chǎn)生大量的內(nèi)存間復(fù)制的開銷,但對(duì)于多數(shù)對(duì)象都是可回收的情況,算法需要復(fù) 制的就是占少數(shù)的存活對(duì)象,而且每次都是針對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,分配內(nèi)存時(shí)也就不用考慮有 空間碎片的復(fù)雜情況,只要移動(dòng)堆頂指針,按順序分配即可。這樣實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效,但 可用內(nèi)存縮小為了原來的一半 。

    標(biāo)記-整理算法

    標(biāo)記-整理算法:其中的標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對(duì)可 回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向內(nèi)存空間一端移動(dòng),然后直接清理掉邊界以外的內(nèi)存。

    缺點(diǎn):

    • 移動(dòng)存活對(duì)象并更新 所有引用這些對(duì)象的地方將會(huì)是一種極為負(fù)重的操作,而且這種對(duì)象移動(dòng)操作必須全程暫停用戶應(yīng)用 程序才能進(jìn)行。

    由以上幾種算法可以看出:是否移動(dòng)對(duì)象都存在弊端,移動(dòng)則內(nèi)存回收時(shí)會(huì)更復(fù)雜,不移動(dòng)則內(nèi)存分配時(shí)會(huì) 更復(fù)雜。從垃圾收集的停頓時(shí)間來看,不移動(dòng)對(duì)象停頓時(shí)間會(huì)更短,甚至可以不需要停頓,但是從整 個(gè)程序的吞吐量來看,移動(dòng)對(duì)象會(huì)更劃算。

    此外就出現(xiàn)了另一種解決方案:

    • 可以不在內(nèi)存分配和訪問上增加太大額外負(fù)擔(dān),做法是讓虛 擬機(jī)平時(shí)多數(shù)時(shí)間都采用標(biāo)記-清除算法,暫時(shí)容忍內(nèi)存碎片的存在,直到內(nèi)存空間的碎片化程度已經(jīng) 大到影響對(duì)象分配時(shí),再采用標(biāo)記-整理算法收集一次,以獲得規(guī)整的內(nèi)存空間。

    垃圾回收算法細(xì)節(jié)實(shí)現(xiàn)

    根節(jié)點(diǎn)枚舉

    在可達(dá)性分析中固定可作為GC Roots的節(jié)點(diǎn)主要在 全局性的引用 (例如常量或類靜態(tài)屬性)與 執(zhí)行上下文 (例如 棧幀中的本地變量表)中,但查找過程要做到高效并非一件容易的事情。也會(huì)造成“Stop The World”的問題。

    HoeSpot虛擬機(jī)的解決方案是:使用一組稱為OopMap的數(shù)據(jù)結(jié)構(gòu)來達(dá)到這個(gè)目的。一旦類加載動(dòng)作完成的時(shí)候, HotSpot就會(huì)把對(duì)象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)計(jì)算出來,在即時(shí)編譯過程中,也 會(huì)在特定的位置記錄下棧里和寄存器里哪些位置是引用。這樣收集器在掃描時(shí)就可以直接得知這些信 息了,并不需要真正一個(gè)不漏地從方法區(qū)等GC Roots開始查找。

    在OopMap的協(xié)助下,HotSpot可以快速準(zhǔn)確地完成GC Roots枚舉,但如果為每一條指令都生成 對(duì)應(yīng)的OopMap,那將會(huì)需要大量的額外存儲(chǔ)空間。

    所以HotSpot虛擬機(jī)并不會(huì)為每條指令都生成OopMap,只是在“特定的位置”記錄 了這些信息,這些位置被稱為 安全點(diǎn) 。

    由于安全點(diǎn)的存在決定了用戶程序執(zhí)行時(shí),并非在代碼指令流的任意位置都能夠停頓下來開始垃圾收集,而是強(qiáng)制要求必須執(zhí)行到達(dá)安全點(diǎn)后才 能夠暫停。

    那么,如何在垃圾收集發(fā)生時(shí)讓所有線程都跑到最近的安全點(diǎn),然后停頓下來呢?這里提供了兩種方案:

  • 搶先式中斷 :在垃圾收集發(fā)生時(shí),系統(tǒng)首先把所有用戶線程全部中斷,如果發(fā)現(xiàn)有用戶線程中斷的地 方不在安全點(diǎn)上,就恢復(fù)這條線程執(zhí)行,讓它一會(huì)再重新中斷,直到跑到安全點(diǎn)上。
  • 主動(dòng)式中斷 :當(dāng)垃圾收集需要中斷線程的時(shí)候,不直接對(duì)線程操作,僅僅簡(jiǎn)單地設(shè)置一 個(gè)標(biāo)志位,各個(gè)線程執(zhí)行過程時(shí)會(huì)不停地主動(dòng)去輪詢這個(gè)標(biāo)志,一旦發(fā)現(xiàn)中斷標(biāo)志為真時(shí)就自己在最 近的安全點(diǎn)上主動(dòng)中斷掛起。
  • 安全區(qū)域

    安全區(qū)域是指能夠確保在某一段代碼片段之中,引用關(guān)系不會(huì)發(fā)生變化,因此,在這個(gè)區(qū)域中任 意地方開始垃圾收集都是安全的。我們也可以把安全區(qū)域看作被擴(kuò)展拉伸了的安全點(diǎn)。

    當(dāng)用戶線程執(zhí)行到安全區(qū)域里面的代碼時(shí),首先會(huì)標(biāo)識(shí)自己已經(jīng)進(jìn)入了安全區(qū)域,那樣當(dāng)這段時(shí) 間里虛擬機(jī)要發(fā)起垃圾收集時(shí)就不必去管這些已聲明自己在安全區(qū)域內(nèi)的線程了。當(dāng)線程要離開安全 區(qū)域時(shí),它要檢查虛擬機(jī)是否已經(jīng)完成了根節(jié)點(diǎn)枚舉,如果完成了,那線程就當(dāng)作沒事發(fā)生過,繼續(xù)執(zhí)行;否則它就必須一直等待,直到收到可以 離開安全區(qū)域的信號(hào)為止。

    記憶集與卡表

    記憶集是一種用于記錄從非收集區(qū)域指向收集區(qū)域的指針集合的抽象數(shù)據(jù)結(jié)構(gòu)。

    它是為了解決分代收集理論中,對(duì)象跨代引用所帶來的問題,而在新生代中建 立了名為記憶集的數(shù)據(jù)結(jié)構(gòu),用以避免把整個(gè)老年代加進(jìn)GC Roots掃描范圍。

    卡表是實(shí)現(xiàn)記憶集的一種方式。

    記憶集是一種“抽象”的數(shù)據(jù)結(jié)構(gòu),它只定義了記憶集的行為意圖,并沒有定義其行為的具體實(shí)現(xiàn)??ū砭褪怯洃浖囊环N具體實(shí)現(xiàn),它定義了記憶集的記錄精度、與堆內(nèi)存的映射關(guān)系等。

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月23日 12:14
    下一篇 2022年6月23日 12:14

    相關(guān)推薦

    • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

      對(duì)于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營(yíng)一個(gè)朋友圈,有的微商看起來逼格滿滿,實(shí)際效果也不錯(cuò);而有的卻動(dòng)都不動(dòng)就被屏蔽甚至拉黑…

      2022年11月27日
    • 筆記本最好配置(目前筆記本最好的配置)

      本文主要講的是筆記本最好配置,以及和目前筆記本最好的配置相關(guān)的知識(shí),如果覺得本文對(duì)您有所幫助,不要忘了將本文分享給朋友。 筆記本電腦什么配置好? 01 CPU:這個(gè)主要取決于頻率和…

      2022年11月26日
    • 11月26日烏魯木齊風(fēng)險(xiǎn)等級(jí)調(diào)整名單

      根據(jù)當(dāng)前疫情防控工作需要,按照《新型冠狀病毒肺炎防控方案(第九版)》、國(guó)務(wù)院聯(lián)防聯(lián)控機(jī)制綜合組《關(guān)于進(jìn)一步優(yōu)化新冠肺炎疫情防控措施科學(xué)精準(zhǔn)做好防控工作的通知》《新冠肺炎疫情風(fēng)險(xiǎn)區(qū)劃…

      2022年11月26日
    • 《寶可夢(mèng)朱紫》夢(mèng)特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢(mèng)朱紫里有很多寶可夢(mèng)都是擁有夢(mèng)特性會(huì)變強(qiáng)的寶可夢(mèng),很多玩家不知道夢(mèng)特性怎么獲得,下面就給大家?guī)韺毧蓧?mèng)朱紫隱藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 《寶可夢(mèng)朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

      寶可夢(mèng)朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧?mèng)朱紫奇魯莉安進(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

      2022年11月25日
    • 百度關(guān)鍵詞快速排名的4大原理解析(百度怎么刷關(guān)鍵詞)

      近期百度公告驚雷算法2.0,升級(jí)之快還是第一次吧,看來百度對(duì)于刷點(diǎn)擊行為是零容忍了。之前尹華峰SEO技術(shù)博客介紹過一篇如何使用刷點(diǎn)擊工具,其實(shí)市面上有很多這類SEO快速排名的軟件,…

      2022年11月25日
    • cpu性能天梯圖2022 AMD CPU天梯圖最新排行榜出爐

      用戶在DIY自己的主機(jī)時(shí)選擇CPU是非常關(guān)鍵的,CPU可以說是電腦的大腦,大家也都想追求好一點(diǎn)的CPU來使用,但型號(hào)太多了,大部分的用戶都不知道目前哪一款CPU比較好用,快來看看詳…

      2022年11月24日
    • 《寶可夢(mèng)朱紫》暴飛龍?jiān)趺醋ィ勘╋w龍獲得方法

      寶可夢(mèng)朱紫暴飛龍位置在哪?在游戲中,很多玩家還不清楚暴飛龍具體要怎么樣獲得,其實(shí)獲得方法很簡(jiǎn)單,暴飛龍直接是沒得抓的,需要玩家從寶貝龍進(jìn)化得到,下面一起來看一下寶可夢(mèng)朱紫暴飛龍獲得…

      2022年11月23日
    • 《寶可夢(mèng)朱紫》布土撥怎么進(jìn)化?布土撥進(jìn)化方法介紹

      寶可夢(mèng)朱紫中,不同的寶可夢(mèng)有不同的進(jìn)化方法,其中布土撥的進(jìn)化方法是比較特殊的。很多玩家不知道寶可夢(mèng)朱紫布土撥怎么進(jìn)化,下面就帶來寶可夢(mèng)朱紫布土撥進(jìn)化方法介紹,一起來看看吧,希望能幫…

      2022年11月23日
    • 《寶可夢(mèng)朱紫》薄荷怎么獲得?薄荷獲得方法

      寶可夢(mèng)朱紫中薄荷有改變寶可夢(mèng)的屬性或性格等效果,很多玩家想知道寶可夢(mèng)朱紫薄荷怎么獲得,下面就帶來寶可夢(mèng)朱紫薄荷獲得方法,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 薄荷獲得方法…

      2022年11月23日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息