搜尋
首頁Javajava教程Java GC的那些事(2)

Java GC的那些事(2)

Feb 22, 2017 am 10:09 AM

收集演算法

垃圾收集演算法主要有:標記-清除、複製和標記-整理。

1、標記-清除演算法

處理回收的物件進行標記。

演算法缺點:效率問題,標記和清除過程效率都很低;空間問題,收集之後會產生大量的記憶體碎片,不利於大物件的分配。

2、複製演算法

複製演算法將可用記憶體分割成大小相等的兩塊A和B,每次只使用其中一塊,當A的記憶體用完了,就把存活的對象複製到B,並清空A的內存,不僅提高了標記的效率,因為只需要標記存活的對象,同時也避免了內存碎片的問題,代價是可用內存縮小為原來的一半。

3、標記-整理演算法

在老年代中,物件存活率較高,複製演算法的效率很低。在標記-整理演算法中,標記出所有存活的對象,並移動到一端,然後直接清理邊界以外的記憶體。

物件標記過程

在可達性分析過程中,為了準確找出與GC Roots相關聯的對象,必須要求整個執行引擎看起來像是被凍結在某個時間點上,即暫停所有運行中的線程,不可以出現物件的引用關係還在不斷變化的情況。

如何快速列舉GC Roots?

GC Roots主要在全域性的引用(常數或類別靜態屬性)與執行上下文(本地變數表中的引用)中,許多應用僅僅方法區就上百兆,如果進行遍歷查找,效率會非常低。

在HotSpot中,使用一組稱為OopMap的資料結構進行實作。類別載入完成時,HotSpot把物件內什麼偏移量上是什麼類型的資料計算出來儲存到OopMap中,透過JIT編譯出來的本機程式碼,也會記錄下棧和暫存器中哪些位置是引用。 GC發生時,透過掃描OopMap的資料就可以快速標識存活的物件。

如何安全的GC?

執行緒運行時,只有在到達安全點(Safe Point)才能停頓下來進行GC。

基於OopMap資料結構,HotSpot可以快速完成GC Roots的遍歷,不過HotSpot並不會為每個指令都產生對應的OopMap,只會在Safe Point處記錄這些資訊。

所以Safe Point的選擇很重要,如果太少可能導致GC等待的時間太長,如果太頻繁可能導致運行時的效能問題。大部分指令的執行時間都非常短暫,通常會選擇一些執行時間較長的指令作為Safe Point,如方法呼叫、循環跳躍和異常跳躍等。

關於Safe Point更多的信息,可以看看這篇文章JVM的Stop The World,安全點,黑暗的地底世界

發生GC時,如何讓所有線程跑到最近的Safe Point再暫停?

當發生GC時,不直接對執行緒進行中斷操作,而是簡單的設定一個中斷標誌,每個執行緒運行到Safe Point的時候,主動去輪詢這個中斷標誌,如果中斷標誌為真,則將自己進行中斷掛起。

這裡忽略了一個問題,當發生GC時,運行中的線程可以跑到Safe Point後進行掛起,而那些處於Sleep或Blocked狀態的線程在此時無法響應JVM的中斷請求,無法到Safe Point處進行掛起,針對這種情況,可以使用安全區域(Safe Region)進行解決。

Safe Region是指在一段程式碼片段中,物件的引用關係不會發生變化,在這個區域中的任何位置開始GC都是安全的。

1、當執行緒運行到Safe Region的程式碼時,首先標識已經進入了Safe Region,如果這段時間內發生GC,JVM會忽略標識為Safe Region狀態的執行緒;

2、當執行緒即將離開Safe Region時,會檢查JVM是否已經完成GC,如果完成了,則繼續運行,否則執行緒必須等待直到收到可以安全離開Safe Region的訊號為止;

垃圾收集器

Java虛擬機器規格並沒有規定垃圾收集器應該如何實現,使用者可以根據系統特點對各個區域所使用的收集器進行組合使用。

Java GC的那些事(2)

上圖展示了7種不同分代的收集器,如果兩兩之間存在連線,表示可以組合使用。

1、Serial收集器(序列GC)

Serial 是採用單一執行緒並基於複製演算法工作在新生代的收集器,進行垃圾收集時,必須暫停其他所有的工作線程。對於單CPU環境來說,Serial由於沒有執行緒互動的開銷,可以很有效率的進行垃圾收集動作,是Client模式下新生代預設的收集器。

2、ParNew收集器(並行GC)

ParNew其實是serial的多執行緒版本,除了使用多個執行緒進行垃圾收集之外,其餘行為與Serial一樣。

3、Parallel Scavenge收集器(並行回收GC)

Parallel Scavenge是一個採用多執行緒基於複製演算法並工作在新生代的收集器,其關注點在於達到一個可控​​的吞吐量,經常被稱為「吞吐量優先」的收集器。

吞吐量= 使用者程式碼運行時間/(使用者程式碼運行時間+ 垃圾收集時間)

#Parallel Scavenge提供了兩個參數用於精確控制吞吐量:

1、-XX:MaxGCPauseMillis 設定垃圾收集的最大停頓時間

2、-XX:GCTimeRatio 設定吞吐量大小

4、Serial Old收集器(序列GC)

Serial Old 是一個採用單執行緒基於標記-整理演算法並工作在老年代的收集器,是Client模式下老年代預設的收集器。

5、Parallel Old收集器(平行GC)

Parallel Old是一個採用多執行緒基於標記-整理演算法並工作在老年代的收集器。在註重吞吐量以及CPU資源敏感的場合,可以優先考慮Parallel Scavenge和Parallel Old的收集器組合。

6、CMS收集器(並發GC)

CMS(Concurrent Mark Sweep)是一種以獲取最短回收停頓時間為目標的收集器,工作在老年代,基於「標記-清除」演算法實現,整個過程分為以下4步:

1、初始標記:這個過程只​​是標記以下GC Roots能夠直接關聯的對象,但仍然會Stop The World;

2、並發標記:進行GC Roots Tracing的過程,可以和使用者執行緒一起工作。

3、重新標記:用於修正並發標記期間由於使用者程式繼續運行而導致標記產生變動的那部分記錄,這個過程會暫停所有執行緒,但其停頓時間遠比並發標記的時間短;

4、並發清理:可以和使用者執行緒一起工作。

CMS收集器的缺點:

1、對CPU資源比較敏感,在並發階段,雖然不會導致用戶執行緒停頓,但會佔用一部分執行緒資源,降低系統的總吞吐量。

2、無法處理浮動垃圾,在並發清理階段,用戶執行緒的運作依然會產生新的垃圾對象,這部分垃圾只能在下次GC時收集。

3、CMS是基於標記-清除演算法實現的,意味著收集結束後會造成大量的記憶體碎片,可能導致出現老年代剩餘空間很大,卻無法找到足夠大的連續空間分配當前對象,不得不提前觸發一次Full GC。

JDK1.5實作中,當老年代空間使用率達到68%時,就會觸發CMS收集器,如果應用中老年代增長不是太快,可以透過-XX:CMSInitiatingOccupancyFraction參數提高觸發百分比,從而降低記憶體回收次數提高系統效能。

JDK1.6實作中,觸發CMS收集器的閾值已經提升到92%,如果CMS運行期間預留的記憶體無法滿足用戶執行緒需要,會出現一次」Concurrent Mode Failure」失敗,這是虛擬機會啟動Serial Old收集器對老年代進行垃圾收集,當然,這樣應用的停頓時間就更長了,所以這個閾值也不能設置的太高,如果導致了”Concurrent Mode Failure”失敗,反而會降低性能,至於如何設定這個閾值,還得長時間的對老年代空間的使用情況進行監控。

7、G1收集器

G1(Garbage First)是JDK1.7提供的一個工作在新生代和老年代的收集器,基於“標記-整理」演算法實現,在收集結束後可以避免記憶體碎片問題。

G1優點:

1、並行與並發:充分利用多CPU來縮短Stop The World的停頓時間;

2、分代收集:不需要其他收集配合就可以管理整個Java堆,採用不同的方式處理新建的物件、已經存活一段時間和經歷過多次GC的物件來獲取更好的收集效果;

#3.空間整合:與CMS的”標記-清除”演算法不同,G1在運行期間不會產生內存空間碎片,有利於應用的長時間運行,且分配大對象時,不會導致由於無法申請到足夠大的連續記憶體而提前觸發一次Full GC;

4、停頓預測:G1中可以建立可預測的停頓時間模型,能讓使用者明確指定在M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒。

使用G1收集器時,Java堆的記憶體佈局與其他收集器有很大區別,整個Java堆會被劃分為多個大小相等的獨立區域Region,新生代和老年代不再是物理隔離了,都是一部分Region(不需要連續)的集合。 G1會追蹤各個Region的垃圾收集情況(回收空間大小和回收消耗的時間),維護一個優先列表,根據允許的收集時間,優先回收價值最大的Region,避免在整個Java堆上進行全區域的垃圾回收,確保了G1收集器可以在有限的時間內盡可能收集更多的垃圾。

不過問題來了:使用G1收集器,一個物件分配在某個Region中,可以和Java堆上任意的物件有引用關係,那麼如何判定物件是否存活,是否需要掃描整個Java堆?其實這個問題在之前收集器中也存在,如果回收新生代的物件時,不得不同時掃描老年代的話,會大大降低Minor GC的效率。

針對這種情況,虛擬機器提供了一個解決方案:G1收集器中Region之間的物件參考關係和其他收集器中新生代與老年代之間的物件參考關係被保存在Remenbered Set資料結構中,用來避免全堆掃描。 G1中每個Region都有一個對應的Remenbered Set,當虛擬機器發現程式對Reference類型的資料進行寫入操作時,會產生一個Write Barrier暫時中斷寫入操作,檢查Reference所引用的物件是否處於相同的Region中,如果不是,則透過CardTable把相關參考資訊記錄到被引用物件所屬Region的Remenbered Set中。

Java GC 的那些事(1)

Java GC的那些事(2)

以上就是Java GC的那些事(2) 的內容,更相關內容請關注PHP中文網(www.php.cn)!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。