JVM學習記錄:垃圾收集演算法
垃圾回收要解決的問題:
哪些內存需要回收?
線程私有區域不需要回收,如PC、Stack、Native Stack;Java 堆和方法區需要
什麼時候回收?
以後的文章解答
如何回收?
首先進行對象存活性的分析,然後利用GC回收演算法進行回收,具體演算法請看下文。
如何判斷對象是否可以回收?
有兩種方式:引用計數演算法和可達性分析演算法,目前主流商業JVM普遍採用可達性分析演算法
引用計數演算法
引用計數演算法顧名思義,為對象的引用計數,每當有一地方引用它時,計數器加1,引用失效(離開作用域時)減1,當計數器值為0時,對象就可以被回收了。引用計數演算法優點是判定效率高,缺點是無法解決對象互相引用的問題,使用此技術進行內存管理的技術有微軟的COM、Flash、Python等
可達性分析演算法
可達性分析演算法,基本思路是以GC Roots為根、向下搜索,所走過的路徑成為引用鏈(Reference Chain),當一個對象到GC
Roots沒有任何引用鏈可達時,就成為此對象不可用,即可以被回收。注意再注意:該演算法的本質是通過找出所有活對象來把其餘空間認定為「無用」,而不是找出所有死掉的對象並回收它們佔用的空間。分代式GC是一種部分收集(partial
collection)的做法。在執行部分收集時,從GC堆的非收集部分指向收集部分的引用,也必須作為GC
roots的一部分。具體到分兩代的分代式GC來說,如果第0代叫做young gen,第1代叫做old gen,那麼如果有minor GC /
young GC只收集young gen里的垃圾,則young gen屬於「收集部分」,而old gen屬於「非收集部分」,那麼從old
gen指向young gen的引用就必須作為minor GC / young GC的GC roots的一部分。
可以作為GC Roots的對象包括:
虛擬機棧 VM Stack 中局部變數表(Local Variables)中引用的對象
方法區中類靜態屬性引用的對象
方法區中常量引用的對象
所有當前被載入的Java類
Java類的運行時常量池裡的引用類型常量(String或Class類型)
String常量池(StringTable)里的引用
VM的一些靜態數據結構里指向GC堆里的對象的引用,例如說HotSpot VM里的Universe里有很多這樣的引用。
本地方法棧中JNI(Native方法)引用的對象
對象引用類型的不同對存活周期的影響:
JDK1.2之後,引用概念得到了擴展,分為強引用Strong、軟引用Soft、弱引用Weak、虛引用Phantom
強引用:一般未指定的,都是強引用,包括Object o = new Object(),只要滿足存活演算法,就不會被回收
軟引用:表示有用但非必須的對象,這些對象在系統將要發生溢出異常之前,進行一次回收,如果回收到還沒有足夠的空間,再拋出異常。
弱引用:其關聯的對象只能生存到下一次垃圾回收之前。
虛引用:不會影響對象的生存時間,也就是說生存時間與強引用一樣,設置虛引用的目的是得到垃圾回收的通知
生存還是死亡?
存活演算法之後,不可達的對象被標記,並進行一次篩選,篩選的條件是「是否有必要執行finalize」,當對象沒有覆蓋此方法或此方法已經被調用過,都將視為沒有必要執行,如果有必要執行,該對象將被放在一個稱為F--Queue的隊列中,並被一個虛擬機建立的線程去執行finalize方法,如果在方法中該對象成功建立了與GC
Roots的引用鏈,他就可以從待回收列表中移除,並繼續存活。
回收方法區
方法區採用永久代實現,相比堆,尤其是新生代,方法區回收的性價比極低,永久代的垃圾回收主要回收廢棄常量和無用的類,參數-verbose:class可以查看類載入和卸載情況
垃圾回收演算法
標記-清除演算法Mark Sweep
先標記,再刪除,缺點是空間利用率低,清除之後會產生大量不連續的內存碎片,浪費內存空間。
複製演算法
將內存分為使用和待用兩部分,當使用部分快滿時,將還存活的對象複製到另外待用部分,然後堆整個使用區域進行回收,優點是回收不會出現內存碎片、缺點是浪費了待用區域的內存空間。商業虛擬機以這種演算法為基礎進行了優化,以HotSpot為例,將內存分為較大的Eden空間和兩個較小的Survivor空間,比例默認是8:1:1,可以通過參數調節,每次使用Eden和一塊Survivor空間,回收時,將這兩個空間存活的對象複製到剩餘的一塊Survivor空間中,並清理掉Eden和第一塊Survivor空間,也就是說可用空間達到了90%,只浪費了10%,這裡有個問題,如果存活對象的超過Survivor空間怎麼辦,這時要依賴一種被稱為分配擔保的機制(Handle
Promotion),將多出的對象分配到老年代。
標記整理演算法
適用於老年代這種存活率高的空間,相比標記清除演算法,標記階段一致,只不過在標記後,會對可回收對象進行整理,讓存活對象向內存一個方向聚集,然後直接清理掉編輯額外的內存。
分代收集演算法
根據存活周期的不同將內存劃分為幾塊,一般把java堆分為新生代和老年代,然後根據不同年代的特點選擇最適合的演算法,比如新生代中的對象朝生夕滅,只有少量存活,比較適合複製演算法,而老年代中對象存活率高,沒有額外空間提供分配擔保,必須使用標記-清除或標記-整理演算法進行回收。
HotSpot演算法實現
枚舉根節點
程序的執行是動態的,與之相關的引用關係也是動態的,所以GC
roots的枚舉和分析必須在一個能保證一致性的快照下進行,JVM是依賴被稱為GC停頓的機制實現,在這個時間點會停頓所有的Java執行線程,即俗稱的」Stop
The World「,GC
Roots的枚舉過程並不是在內存中便利所有對象和執行上下文,那樣效率無疑會很低,其實在Class載入和解析的工作中,HotSpot已經使用一組稱為OopMap的結構對GC
Roots進行標記,這樣在GC過程中即可直接獲得Roots信息。
安全點 SafePoint
那麼GC停頓是如何讓線程暫停的呢?有一個關鍵的概念叫安全點,顧名思義是指一些特定的位置,當線程運行到這些位置時,線程的一些狀態可以被確定(the
thread"s representation of it"s Java machine state is well
described),比如記錄OopMap的狀態,從而確定GC Root的信息,使JVM可以安全的進行一些操作,比如開始GC。
另一個問題是GC如何讓線程在安全點上停頓下來,有兩種方式可選,一種是搶先式中斷,GC主動中斷所有線程,發現有線程中斷的地方不在安全點上,就恢複線程,讓它繼續跑到安全點上,一種是主動式中斷,GC不主動中斷線程,而是設置一個標誌,線程執行時主動去輪詢這個標誌,發現標誌為真就自動掛起,輪詢標誌和安全點是重合的。
safepoint指的特定位置主要有:
循環的末尾 (防止大循環的時候一直不進入safepoint,而其他線程在等待它進入safepoint)
方法返回前
調用方法的call之後
拋出異常的位置
安全區域 SafeRegion
安全點沒有解決一個問題,就是當線程不執行的時候(如進入Sleep或Blocked狀態),這時候線程無法響應JVM的中斷請求,這就需要安全區域這種機制來解決。安全區域是指一段代碼範圍,這個範圍內任何位置引用關係都不會發生變化,也就是說在這些位置進行GC是安全的,你可以把安全區域看成被擴展了的安全點。
線程在進入安全區域後會標識自己已經進入了安全區域,這樣GC就會忽略這個線程,同樣離開安全區域時,線程要檢查GC是否完成了根節點枚舉,如果完成,線程繼續進行,否則繼續等待。
更多IT精品課程,訪問中公優就業官網:http://xue.ujiuye.com
勤工儉學計劃」,給你一個真正0元學習IT技術的機會!
http://www.ujiuye.com/zt/qgjx/?wt.bd=lsh
找工作太難?不是你不行,我們來幫你!
http://www.ujiuye.com/zt/jyfc/?wt.bd=lsh
※回首2010,是什麼決定了BAT三巨頭的格局?
※有人告訴我一篇文章就可以學會Gulp(Getting started with Gulp)!你敢信?
※Entity Framework Core 執行SQL語句和存儲過程
※TypeScript01 編譯環境的搭建、字元串特性
※什麼是最全的CSS hack?這就是最全的CSS hack沒有之一!
TAG:IT優就業 |
※NLP學習記錄——句法分析
※H3C學習記錄
※記錄女王BLACKPINK再得獎 榮獲日本VMAJ最佳舞蹈獎
※ASML季報深度解讀:EUV銷售創記錄
※《i記錄》:分享學習的方法
※普法眼高清執法記錄儀DSJ-PF1廠家直銷
※EUV訂單瘋長,ASML創下新的銷售記錄
※Intel打破斯坦福深度學習測試記錄:力壓谷歌/NVIDIA
※更換IPhone電池記錄
※MKiyo記錄:汕頭美食
※Otter的免費應用程序將語音記錄帶入AI時代
※如何清除Windows中的RDP連接歷史記錄
※詹姆斯主演電影,Eminem新單破記錄︱直男Daily
※利用CRISPR/Cas9為DNA照相,新型細胞記錄儀捕獲DNA數據
※BLACKPINK日本巡演追加場次!創下巨蛋演出記錄!
※視頻好夥伴——ATOMOS 監視記錄儀
※Blackpink刷新KPOP男女團歷代最短時間歌曲MV破2億記錄!
※自定義註解+springMVC配置攔截器記錄用戶操作的日誌(寫入資料庫)
※Spring AOP 實現日誌記錄功能
※手機壞了自己修,男士必備新技能—HUAWEI 華為 Mate9 手機換屏記錄