在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從原理聊JVM(一):染色標記和垃圾回收算法

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-08-20 15:25 ? 次閱讀

導讀

JAVA簡單易用的特性,能夠讓研發人員在不了解JVM的底層運行機制的情況下依舊能夠編寫出功能完善的代碼。

但是對JVM的理解,是一個程序員普通和優秀的分水嶺。全面地了解JVM的工作原理,能夠更好地優化自己的代碼,并解決一些潛在的性能問題。

本文及后續文章將從原理聊起,對JVM的內存分配、GC、編譯等知識進行分析和總結。

1 JVM運行時內存劃分

1.1 運行時數據區域

wKgaombERMKAIkVjAAHROjCUdGM843.png

??

?方法區

屬于共享內存區域,存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。運行時常量池,屬于方法區的一部分,用于存放編譯期生成的各種字面量和符號引用。

JDK1.8之前,Hotspot虛擬機對方法區的實現叫做永久代,1.8之后改為元空間。二者區別主要在于永久代是在JVM虛擬機中分配內存,而元空間則是在本地內存中分配的。很多類是在運行期間加載的,它們所占用的空間完全不可控,所以改為使用本地內存,避免對JVM內存的影響。根據《Java虛擬機規范》的規定,如果方法區無法滿足新的內存分配需求時,將拋出OutOfMemoryError異常。

?

線程共享,主要是存放對象實例和數組。如果在Java堆中沒有內存完成實例分配,并且堆也無法再擴展時,Java虛擬機將會拋出OutOfMemoryError異常。PS:實際上寫入時并不完全共享,JVM會為線程在堆上劃分一塊專屬的分配緩沖區來提高對象分配效率。詳見:TLAB

?虛擬機棧

線程私有,方法執行的過程就是一個個棧幀從入棧到出棧的過程。每個方法在執行時都會創建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。如果線程入棧的棧幀超過限制就會拋出StackOverFlowError,如果支持動態擴展,那么擴展時申請內存失敗則拋出OutOfMemoryError。

?本地方法棧

和虛擬機棧的功能類似,區別是作用于Native方法。

?程序計數器

線程私有,記錄著當前線程所執行的字節碼的行號。其作用主要是多線程場景下,記錄線程中指令的執行位置。以便被掛起的線程再次被激活時,CPU能從其掛起前執行的位置繼續執行。唯一一個在 Java 虛擬機規范中沒有規定任何 OutOfMemoryError 情況的區域。注意:如果線程執行的是個java方法,那么計數器記錄虛擬機字節碼指令的地址。如果為native(底層方法),那么計數器為空。

1.2 對象的內存布局

在 HotSpot 虛擬機中,對象分為如下3塊區域:

?對象頭(Header)運行時數據:哈希碼、GC分代年齡、鎖狀態標志、偏向線程ID、偏向時間戳等。類型指針:對象的類型元數據的指針,如果對象是數據,還會記錄數組長度。

?對象實例數據(Instance Data)包含對象真正的內容,即其包括父類所有字段的值。

?對齊填充(Padding)對象大小必須是是8字節的整數倍,所以對象大小不滿足這個條件時,需要用對齊填充來補齊。

2 標記的方法和流程

2.1 判斷對象是否需要被回收

要分辨一個對象是否可以被回收,有兩種方式:引用計數法可達性算法

?引用計數法就是在對象被引用時,計數加1,引用斷開時,計數減1。那么一個對象的引用計數為0時,說明這個對象可以被清除。這個算法的問題在于,如果A對象引用B的同時,B對象也引用A,即循環引用,那么雖然雙方的引用計數都不為0,但如果僅僅被對方引用實際上沒有存在的價值,應該被GC掉。

?可達性算法通過引用計數法的缺陷可以看出,從被引用一方去判定其是否應該被清理過于片面,所以我們可以通過相反的方向去定位對象的存活價值:一個存活對象引用的所有對象都是不應該被清除的(Java中軟引用或弱引用在GC時有不同判定表現,不在此深究)。這些查找起點被稱為GC Root。

2.2 哪些對象可以作為GC Root呢?

1.JAVA虛擬機棧中的本地變量引用對象

2.方法區中靜態變量引用的對象

3.方法區中常量引用的對象

4.本地方法棧中JNI引用的對象

2.3 快速找到GC Root - OopMap

棧與寄存器都是無狀態的,保守式垃圾收集會直接線性掃描棧,再判斷每一串數字是不是引用,而HotSpot采用準確式垃圾收集方式,所有對象都存放在OopMap(Ordinary Object Pointer)中,當GC發生時,直接從這個map中尋找GC Root。

將GC Root存放到OopMap有兩個觸發時間點:

1.類加載完成后,HotSpot就會把對象內什么偏移量上是什么類型的數據計算出來。

2.即時編譯過程中,也會在特定的位置記錄下棧里和寄存器里哪些位置是引用。

2.4 更新OopMap的時機 - 安全點

導致OopMap更新的指令非常多,所以HotSpot只在特定位置進行記錄更新,這些位置叫做安全點。安全點位置的選取的標準是:“是否具有讓程序長時間執行”。比如方法調用、循環跳轉、異常跳出等等。

2.5 可達性分析過程

三色標記法

?白色:表示垃圾回收過程中,尚未被垃圾收集器訪問過的對象,在可達性分析開始階段,所有對象都是白色的,即不可達。

?黑色:被垃圾收集器訪問過的對象,且這個對象所有的引用均掃描過。黑色的對象是安全存活的,如果其他對象被訪問時發現其引用了黑色對象,該黑色對象也不會再被掃描。

?灰色:被垃圾收集器訪問過的對象,但這個對象至少有一個引用的對象沒有被掃描過。那么標記階段就是從GC Root的開始,沿著其引用鏈將每一個對象從白色標記為灰色最后標記為黑色的過程。

標記過程中不一致問題

由于這個階段是層層遞進的標記,所以過程中難免出現不一致的情況導致原本是黑色的對象被標記為白色,比如,當前掃描到B對象了,C對象尚未被訪問時,標記情況如下:

wKgZombERMOAO-txAAAsjteoOf8539.png

那么如果這時A對象取消了對B對象的引用,而GC Root增加了對C對象的引用,GC Root作為黑色標記不會再次被掃描,那么C對象在標記階段結束后仍然會保持白色,就會被清除掉。

wKgaombERMOAFsbkAAA5d9WuaBM141.png

解決方式

?增量更新

當黑色對象增加了對白色對象的引用時,將其從黑色改為灰色,等并發標記階段結束后,從GC Root開始順著對象圖再將灰色對象重新掃描一次,這個掃描過程會STW,不會再次產生不一致問題。CMS就采用了這種方式。

?原始快照(SATB)

當灰色對象刪除了白色對象的引用時,將其記錄在線程獨占的SATB Queue中,讓其在標記階段結束后被再次掃描。 G1、Shenandoah采用了這種方式。

示例

我們通過一個例子來展示兩種處理方式的不同,比如正常標記到對象A時,將其標記為灰色:

wKgZombERMSAGd95AAApxOmPhtU488.png

此時,用戶線程發生如下行為:

1.GC Root直接引用了C

2.A取消了引用B

理論上,C仍然是可達對象,不應被清除,而B不可達,應當被清除。

wKgZombERMWAfE91AAA2q4bUlHw904.png

增量更新會記錄行為1,將GC Root標記為灰色,B不能訪問到被標記為可以回收

wKgaombERMmASFT9AAA17Jd0In4144.png

等到重新標記階段再次訪問灰色的GC Root,順序將GC Root和C標記為黑色:

wKgZombERMyAAn8fAAA2XWh-BpE186.png

而原始快照會記錄行為2,將發生引用變化的對象全部記錄下來,等到重新標記階段再次訪問這些灰色,將其標記為黑色并順著對象圖掃描。

wKgZombERM2AMeh_AABeptJlui4287.png

那么最終B作為浮動垃圾就被保存下來了,只能等到下一次GC時才能被回收。

3 分代模型

3.1 分代假說

弱分代假說(WeakGenerationalHypothesis):絕大多數對象都是朝生夕滅的。 強分代假說(StrongGenerationalHypothesis):熬過越多次垃圾收集過程的對象就越難以消亡。 跨代引用假說(IntergenerationalReferenceHypothesis):跨代引用相對于同代引用來說僅占極少數。

上述假說是根據實際經驗得來的,由此垃圾收集器通常分為“年輕代”和“年老代”:

?年輕代用來存放不斷生成且生命周期短暫的對象,收集動作相對高頻

?年老代用來存放經歷多次GC仍然存活的對象,收集動作相對低頻

3.2 空間分配擔保

如果在GC后新生代存貨對象過多,Survivor無法容納,那么將會把這些對象直接送入年老代,這就叫年老代進行了“分配擔保”。 為了保證年老代能夠足夠空間容納這些直接晉升的對象,在發生Minor GC之前,虛擬機必須先檢查年老代最大可用的連續空間,如果大于新生代所有對象總空間或者歷次晉升的平均大小,就會進行MinorGC,否則將進行FullGC以同時清理年老代。

3.3 記憶集和卡表

記憶集是一種用于記錄從非收集區域指向收集區域的指針集合的抽象數據結構。

記憶集的作用

新生代發生垃圾收集時(Minor GC),如果想確定這個新生代對象是否被年老代的對象引用,則需要掃描整個年老代,成本非常高。

如果我們能知道哪一部分年老代可能存在對新生代的引用,就可以降低掃描范圍。

所以我們可以在新生代建立一個全局數據結構叫“記憶集(Remembered Set)”,這個結構把年老代分為若干個小塊,標記了哪些小塊內存中存在引用了新生代對象的情況,等到Minor GC時,只掃描這部分存在跨代引用的內存塊即可。雖然在對象變化時增加了維護記憶集的成本,但相比垃圾收集時掃描整個年老代來說是值得的。

JVM通常在對象增加引用前設置寫屏障判斷是否發生跨代引用,如果有跨代情況,則更新記憶集。

卡表

實現記憶集時,可以有不同精度的粒度:可以指向內存地址,也可以指向某個對象,或者指向某一塊內存區域。精度越低,維護成本越低。指向某一塊內存區域的實現方式就是“卡表”。卡表通常就是一個byte數組,數組中每一個元素代表某一塊內存,其值是1或者0:當發生跨代引用時,就表示該元素“dirty”了,那么將將其設置為1,否則就是0。

wKgaombERM6AEETyAABsrdTtdOc939.png

4 垃圾回收算法

4.1 標記-清除(Mark-Sweep)

GC分為兩個階段,標記和清除。首先標記所有可回收的對象,在標記完成后統一回收所有被標記的對象。

缺點是清除后會產生不連續的內存碎片。碎片過多會導致以后程序運行時需要分配較大對象時,無法找到足夠的連續內存,而不得已再次觸發GC。

wKgZombERM-ATf12AAFWomdafMs003.png

4.2 標記-復制(Mark-Copy)

將內存按容量劃分為兩塊,每次只使用其中一塊。當這一塊內存用完了,就將存活的對象復制到另一塊上,然后再把已使用的內存空間一次清理掉。

這樣使得每次都是對半個內存區回收,也不用考慮內存碎片問題,簡單高效。

wKgaombERNCASAhcAAFW9rWl_iY234.png

缺點需要兩倍的內存空間。

一種優化方式是使用eden和survivior區,具體步驟如下:

eden和survivior區默認內存空間占比為8:1:1,同一時間只使用eden區和其中一個survivior區。標記完成后,將存活對象復制到另一個未使用的survivior區(部分年齡過大的對象將升級到年老代)。

這種做法,相比普通的兩塊空間的標記復制算法來說,只有10%的內存空間浪費,而這樣做的原因是:大部分情況下,一次young gc后剩余的存活對象非常少

wKgaombERNWAT6NeAABnHaX5duM018.png

4.3 標記-整理(Mark-Compact)

標記-整理也分為兩個階段,首先標記可回收的對象,再將存活的對象都向一端移動,然后清理掉邊界以外的內存。

wKgaombERNiAMnmqAAJ6Rs95j3c612.png

此方法避免標記-清除算法的碎片問題,同時也避免了復制算法的空間問題。 一般年輕代中執行GC后,會有少量的對象存活,就會選用復制算法,只要付出少量的存活對象復制成本就可以完成收集。

而年老代中因為對象存活率高,用標記復制算法時數據復制效率較低,且空間浪費較大。所以需要使用標記-清除或者標記-整理算法來進行回收。

所以通常可以先使用標記清除算法,當碎片率高時,再使用標記整理算法。

5 最后

本篇介紹了JVM中垃圾回收器相關的基礎知識,后續會深入介紹CMS、G1、ZGC等不同垃圾收集器的運作流程和原理,歡迎關注。

?

系列文章:

從原理聊JVM(一):染色標記和垃圾回收算法

從原理聊JVM(二):從串行收集器到分區收集開創者G1

從原理聊JVM(三):詳解現代垃圾回收器Shenandoah和ZGC

從原理聊JVM(四):JVM中的方法調用原理

從原理聊JVM(五):JVM中的編譯過程和優化手段?

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4675

    瀏覽量

    94191
  • 內存
    +關注

    關注

    8

    文章

    3096

    瀏覽量

    74828
  • JVM
    JVM
    +關注

    關注

    0

    文章

    159

    瀏覽量

    12444
收藏 人收藏

    評論

    相關推薦

    如何眼定位SQL的代碼來源:款SQL染色標記的簡易MyBatis插件

    作者:京東物流 郭忠強 導語 本文分析了后端研發和運維在日常工作中所面臨的線上SQL定位排查痛點,基于姓名貼的靈感,設計和開發了款SQL染色標記的MyBatis插件。該插件輕量高效,對業務代碼無
    的頭像 發表于 03-05 11:36 ?263次閱讀
    如何<b class='flag-5'>一</b>眼定位SQL的代碼來源:<b class='flag-5'>一</b>款SQL<b class='flag-5'>染色</b><b class='flag-5'>標記</b>的簡易MyBatis插件

    物聯網+垃圾桶滿溢檢測器回收系統解決方案

    、方案背景 今年垃圾分類正式進入大眾視野,不僅成為普通百姓最關心的話題,也再次將垃圾分類行業推向市場焦點。由此可見,隨著垃圾分類制度的進
    的頭像 發表于 01-02 15:58 ?525次閱讀
    物聯網+<b class='flag-5'>垃圾</b>桶滿溢檢測器<b class='flag-5'>回收</b>系統解決方案

    智能垃圾投放站遠程監控智慧運維系統方案

    隨著環保意識的提高和政策的推動,垃圾分類已成為全球發展的重要主題。我國持續推進垃圾分類和回收等相關產業的發展,鼓勵居民和企業進行垃圾分類和回收
    的頭像 發表于 12-31 15:47 ?247次閱讀

    垃圾短信?手機自動識別垃圾短信邏輯的分析

    作者:京東科技 賈玉龍 1 背景 隨著智能手機的普及和移動互聯網的發展,短信作為種傳統的通訊方式,仍然保持著其獨特的地位。然而,隨著垃圾短信的泛濫,手機自動識別垃圾短信的技術也在不斷進步。對于提供
    的頭像 發表于 12-16 10:19 ?639次閱讀

    ?ISP算法及架構分析介紹

    ),結果上看就是將RAW數據轉換成壓縮后的RGB(般)數據,供后續CPU使用(識別、壓縮等)。 市面上很少有直接介紹ISP的書籍或者資料,今天我們主要是
    的頭像 發表于 11-26 10:05 ?1262次閱讀
    ?ISP<b class='flag-5'>算法</b>及架構分析介紹

    JVM xmx, xms等內存相關參數合理性設置

    作者:京東零售 劉樂 上篇文章說到JVM垃圾回收算法的兩個優化標的:吞吐量和停頓時長,并提到這兩個優化目標是有沖突的。那么有沒有可能提高吞
    的頭像 發表于 10-10 14:42 ?949次閱讀

    智能回收箱的功能和使用步驟介紹

    智能回收箱是現代城市環保與資源循環利用領域的項創新技術,它通過集成各種智能化功能,提高了垃圾回收的效率和準確性,促進了垃圾分類與減量。隨著
    的頭像 發表于 09-23 14:34 ?1871次閱讀
    智能<b class='flag-5'>回收</b>箱的功能和使用步驟介紹

    聊聊JVM如何優化

    首先應該明確的是JVM調優不是常規手段,JVM的存在本身就是為了減輕開發對于內存管理的負擔,當出現性能問題的時候第時間考慮的是代碼邏輯與設計方案,以及是否達到依賴中間件的瓶頸,最后才是針對J
    的頭像 發表于 08-05 17:49 ?638次閱讀
    聊聊<b class='flag-5'>JVM</b>如何優化

    基于PYNQ的智能垃圾分類系統

    的問題,減輕社會和居民的壓力,如果可以實現可回收垃圾二次分類,對生活垃圾自主分類就顯得尤為重要。于此,我們決定設計這樣個作品—智能識別自動投遞分類
    發表于 07-09 18:44

    RFID智慧環衛護航城市垃圾精細化管理

    。而RFID技術作為物聯網技術的重要組成部分,正在改變著城市的管理方式和效率,為智慧城市的發展提供了強大支持。 為解決城市小區垃圾回收問題,采用 RFID技術 對城市垃圾進行回收與監管
    的頭像 發表于 06-20 10:14 ?470次閱讀
    RFID智慧環衛護航城市<b class='flag-5'>垃圾</b>精細化管理

    MK米客方德SD NAND的垃圾回收機制

    無人機在各個領域的應用日益廣泛,航拍、物流配送到農業監測,無人機正逐漸成為我們生活中不可或缺的部分。作為種創新的存儲芯片,SD NAND因其小巧的尺寸、高可靠性和高速接口,尤其適用于空間有限
    的頭像 發表于 06-05 14:00 ?878次閱讀
    MK米客方德SD NAND的<b class='flag-5'>垃圾</b><b class='flag-5'>回收</b>機制

    智能垃圾回收箱功能實驗

    需要系統地介紹智能垃圾回收箱軟件硬件設計完成后的設備運行狀況,包括正常工作和問題調試。同時,也要描述當所有設備正常工作時智能垃圾回收箱的操作流程。01硬件模塊的試驗在智能
    的頭像 發表于 05-24 08:10 ?692次閱讀
    智能<b class='flag-5'>垃圾</b><b class='flag-5'>回收</b>箱功能實驗

    垃圾清運以及垃圾處理“神器”讓垃圾清運更高效。

    隨著城市功能的不斷豐富,城市管理工作也粗放到精細、純人工管理到數字化應用逐漸轉變。近日,某小區垃圾滿溢監測“神器”上線,能夠實時監控區內果皮箱的數量、位置、垃圾量情況,讓
    的頭像 發表于 05-13 09:37 ?526次閱讀
    <b class='flag-5'>垃圾</b>清運以及<b class='flag-5'>垃圾</b>處理“神器”讓<b class='flag-5'>垃圾</b>清運更高效。

    垃圾中轉站無人值守物聯網解決方案

    收集點的垃圾,進行分類分揀與處理回收,隨后再轉運到焚燒廠、填埋場或回收站等進行最終處理。隨著各種智能裝備的加入,如壓濾設備、污水處理設備、廢氣凈化設備等,為垃圾中轉提供高效率低成本的工
    的頭像 發表于 04-19 11:22 ?918次閱讀
    <b class='flag-5'>垃圾</b>中轉站無人值守物聯網解決方案

    智能垃圾回收箱系統軟件設計

    智能垃圾回收箱自動分揀、智能感知智能垃圾回收箱是物聯網設備,通常支持聯網和與手機應用程序進行交互等功能。這些功能需要可靠的云平臺支持,因此選擇合適的云平臺至關重要。物聯網平臺選擇機智云
    的頭像 發表于 04-19 08:10 ?722次閱讀
    智能<b class='flag-5'>垃圾</b><b class='flag-5'>回收</b>箱系統軟件設計
    主站蜘蛛池模板: 二区三区 | 男男扒开后菊惩罚 | 狠狠操狠狠插 | 一级毛片免费不卡直观看 | 日本黄页网 | 色视频综合 | 在线天堂bt中文www在线 | 日韩高清成人毛片不卡 | 日本黄视频在线观看 | 女人aaaaa片一级一毛片 | 啪啪免费网站 | 四虎国产成人亚洲精品 | 波多野结衣在线观看一区二区 | 亚洲精品成人a在线观看 | 欧美射射射| 亚洲性色成人 | 亚欧精品一区二区三区 | 欧美爽妇| 午夜爽爽 | 人人添人人澡人人澡人人人爽 | 免费看欧美理论片在线 | 色香视频一sxmv首页 | 男操女免费视频 | 99热久久精品最新 | 性色aⅴ闺蜜一区二区三区 性色成人网 | avbobo官网在线入口 | 久久青草免费免费91线频观看 | 国产黄色在线看 | 男人和女人在床做黄的网站 | 亚洲www网站| 亚洲国产成人久久午夜 | 三级电影在线观看视频 | 男人的天堂在线视频 | 国产免费高清视频在线观看不卡 | 美脚连裤袜老师正在播放 | 亚洲午夜视频 | 国产香蕉75在线播放 | 天天免费看片 | 最近高清在线视频观看免费 | 国产情侣自拍小视频 | 特级全黄一级毛片免费 |