第三章:垃圾回收器:垃圾回收器的兩種算法
阿新 • • 發佈:2019-04-01
是否 div 搜索路徑 word position 其他 範圍 ava 對象實例 垃圾回收需要考慮三個問題:
哪些內存需要回收?
什麽時候回收?
如何回收?
JVM中程序計數器、虛擬機棧、本地方法三個區域隨線程而生,隨線程而死,這三個區域的內存分配和回收都具有確定性,在這個幾個區域不需要過多考慮回收的問題,因為方法結束或者線程結束時,內存自然就隨著回收了。
而Java堆和方法區則不一樣,一個接口中的多個實現類需要的內存可能不一樣,一個方法中的不同分支需要的內存也可能不一樣,我們只能在運行期間才能知道會創建哪些對象,這部分內存的分配和回收時動態的,垃圾收集器主要關註的是這部分區域。
在Java堆中存放著java世界幾乎所有的對象實例,垃圾回收器在對堆進行回收前,首要意見事就是確定哪些還存活著,哪些已經死去(即再不可能被任何途徑使用的對象)
即使可達性算法中不可達的對象,也並非時“非死不可”,這時候他們這哪是處於“緩刑”節點,要真正宣告一個對象死亡,至少要經理兩次標記過程:如果對象在進行可達性分析後發現沒有雨GC Roots相連的引用鏈,那麽它將會被第一次標記並且進行一次篩選,篩選的條件是此對象是否有必要執行finalize方法。當對象沒有覆蓋finalize方法或者finalize方法已經被虛擬機調用過了,虛擬機將這種情況視為“沒有必要執行”。
如果一個對象被判定為有必要執行finalize方法,那麽這個對象將會放置在一個叫做F-Queue的隊列中,並在稍後有一個由虛擬機自動建立的、低優先級的Finalizer線程去執行它,這裏所謂的執行是指虛擬機會觸發這個方法,當時並不會承諾登臺它運行結束,這樣做的原因是防止F-Queue隊列中其他對象永遠處於等待甚至發生了死循環,從而影響整個內存回收奔潰。
finalize是對象逃脫死亡的最後一次機會。如果在進行第二次標記時,對象要在finalize中成功拯救自己,只要重新與引用鏈上的任何一個對象建立關聯即可。
需要註意的一點是:任何一個對象的finalize方法都只會被系統自動調用一次。
- 引用計數器算法
- 可達性分析算法
- 強引用:可以理解為Object ob = new Object(),這種代碼中普遍存在的引用,只要強引用還在,垃圾回收器就不會進行回收;
- 軟引用:用來描述一些還有用但是並非必需的對象,對於軟引用關聯的隊盎,在系統將要發生內存溢出異常前,將會把這些對象列進回收範圍值周進行二次回收,如果這次回收還沒有足夠的內存,才會拋出內存溢出異常。
- 弱引用:用來描述非必要的對象的,但是它的強度比軟引用更弱一些,被弱引用關聯的對象之鞥呢存活到下一次垃圾收集發生之前,當垃圾回收器工作時,無論當前的內存是否足夠,都會回收掉被弱引用關聯的對象。
- 虛引用:它是最弱額的一種引用關系,一個對象是否是虛引用完全不會對其生命時間構成影響,也無法通過虛引用來取得一個對象實例。為一個對象設置虛引用關聯的唯一目的就是能在這個對象被收集器回收時收到一個系統通知。
第三章:垃圾回收器:垃圾回收器的兩種算法