免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

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

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

      文章目錄

      對象是否存活?

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

      判斷對象是否存活有以下兩種算法

      引用計數(shù)法

      在對象中添加一個引用計數(shù)器,每當有一個地方引用它時,計數(shù)器的值就 +1 ;當引用失效時,計數(shù)器值就-1 ;任何時刻計數(shù)器為 0 的對象就是不可能再被使用的。

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

      例如,存在兩個對象象 objA 和 objB ,他們都有字段instance,令 objA.instance=objB;objB.instance=objA 。除此之外,這兩個對象再無任何引用,實際上這兩個對象已經(jīng) 經(jīng)不可能再被訪問,但是它們因為互相引用著對方,導致它們的引用計數(shù)都不為零,引用計數(shù)算法也就無法回收它們。

      可達性分析法

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

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

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

      強、軟、弱、虛

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

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

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

      • 任何一個對象的finalize()方法都只會被系統(tǒng)自動調用一次,如果對象面臨 下一次回收,它的finalize()方法不會被再次執(zhí)行;
      • 虛擬機會觸發(fā)finalize方法開始運行,但并不承諾一定會等待它運行結束。

      垃圾收集算法

      分代收集理論

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

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

      三個假說:

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

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

      缺點:

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

      標記-復制算法

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

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

      標記-整理算法

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

      缺點:

      • 移動存活對象并更新 所有引用這些對象的地方將會是一種極為負重的操作,而且這種對象移動操作必須全程暫停用戶應用 程序才能進行。

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

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

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

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

      根節(jié)點枚舉

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

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

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

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

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

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

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

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

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

      記憶集與卡表

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

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

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

      記憶集是一種“抽象”的數(shù)據(jù)結構,它只定義了記憶集的行為意圖,并沒有定義其行為的具體實現(xiàn)。卡表就是記憶集的一種具體實現(xiàn),它定義了記憶集的記錄精度、與堆內(nèi)存的映射關系等。

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

      相關推薦

      • 常態(tài)化防控跟低風險哪個嚴重(常態(tài)化防控區(qū)域是低)

        最近有關疫情低風險地區(qū)和常態(tài)化防控政策也是各地民眾比較關注的,很多小伙伴一直弄不清楚常態(tài)化防控和低風險之間的區(qū)別。常態(tài)化防控跟低風險哪個嚴重?這兩個防疫政策到底有何不同呢?下面來看…

        2022年10月21日
      • 中國“垃圾”國貨緊急大曝光!強烈建議看看!還是國貨良心

        建議各位不要輕易嘗試這些國貨 我怕你用一次就愛上了 不僅價格便宜,還特別好用 用澳芙氧氣洗面奶,臉上清爽不長豆了 用詩麗繽紛橙花面膜,熬夜叫不黃 用Nebe櫻花身體乳,腿上光滑了 …

        2022年6月30日
      • 12GB+256GB大容量,這4款手機最低僅1749元,正常能用三五年不卡

        您在閱讀前請點擊上面的“關注”二字,后續(xù)會第一時間為您提供更多有價值的相關內(nèi)容,感謝您的支持。 隨著手機性能的提升,現(xiàn)在人們更換手機的頻率越來越低,購買手機后想要使用3~5年,這樣…

        2022年8月14日
      • 菜炒咸了怎么辦?炒菜50年大廚:教你個方法,炒菜立刻又香又好吃

        一道色香味俱全的菜肴,除了離不開對食材的了解,營養(yǎng)均衡葷素的合理搭配,合適的烹飪方法,更重要的就是關鍵到味道的調味料比例。一道菜肴好不好吃?靠的是我們的味覺去感覺!鹽是百味之本,烹…

        2022年8月22日
      • 正確分析自己

        大家好,歡迎來到零基礎學化妝的課堂。前面的三節(jié)基礎課程,我們一起了解了該如何學習化妝,新手如何選擇化妝品以及基本的護膚常識。接下來我們就要進入化妝的學習階段,還記得我們的化妝等于百…

        2022年7月4日
      • 英語成績一直提高不了怎么辦?

        在五年前,我也遇到過這個問題。 那個時候筆者剛剛升入高三,滿分為,150分英語,在高二升高三的考試中,卷面分數(shù)只有50分。 記得剛進班的那天,是按成績分的位置,筆者坐在了最后一排?!?/p>

        2022年6月5日
      • 英仙座流星雨本周將達到頂峰:以下是觀看方法

        每年一次,從 7 月中旬到 8 月下旬,地球會經(jīng)過一個宇宙垃圾堆,向我們的星球投擲數(shù)以千計的微小太空巖石,其寬度不超過一粒沙子。我們稱這一年度事件為 英仙座流星雨 ——或簡稱為英仙…

        2022年8月17日
      • 中國公認垃圾洗發(fā)水緊急大曝光!強烈建議扔掉,海飛絲,清揚上榜

        不是所有好用的洗發(fā)水都是外國的 國貨也有很多好用洗發(fā)水 不僅好用還很平價 妥妥的實力派 不僅防脫發(fā)還可以柔順秀發(fā) 性jia比也太高了 有需要的小姐妹趕緊囤起來吧

        2022年6月25日
      • 宇宙 第三集-宇宙的混沌邊界

        所謂的混沌邊界條件即是這樣一種可能性。這里含蓄地假定,要么宇宙是空間無限的,要么存在無限多宇宙。在混沌邊界條件下,在剛剛大爆炸之后,尋求任何空間的區(qū)域在任意給定的結構的概率,在某種…

        2022年8月14日
      • Java常見陷阱(pitfalls)分析

        1 using == to compare primitive wrappers objects such as Integer Integer int1_1 = Integer.…

        2022年6月19日

      聯(lián)系我們

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