垃圾標記階段: 對象存活判斷
- 在堆里存放著幾乎所有的Java對象實例,在GC執(zhí)行垃圾回收之前,首先
需要區(qū)分出內(nèi)存中哪些是存活對象,哪些是已經(jīng)死亡的對象陶缺。
只有被標記為已經(jīng)死亡的對象,GC才會在執(zhí)行垃圾回收時,釋放掉其所占用的內(nèi)存空間,因此這個過程我們可以稱為垃圾標記階段叫搁。 - 那么在JVM中究竟是如何標記一個死亡對象呢?簡單來說,當一個對象已經(jīng)不再被任何的存活對象繼續(xù)引用時,就可以宣判為已經(jīng)死亡。
- 判斷對象存活一般有兩種方式:
引用計數(shù)算法
和可達性分析算法
愕鼓。
引用計數(shù)算法
- 引用計數(shù)算法(Reference Counting)比較簡單,對每個對象保存一個整型的
引用計數(shù)器屬性。用于記錄對象被引用的情況。
- 對于一個對象A,只要有任何一個對象引用了A,則A的引用計數(shù)器就加1;當引用失效時,引用計數(shù)器就減1。只要對象A的引用計數(shù)器的值為0,即表示對象A不可能再被使用,可進行回收曹货。
- 優(yōu)點:
實現(xiàn)簡單,垃圾對象便于辨識;判定效率高,回收沒有延遲性。
- 缺點:
- 它需要單獨的字段存儲計數(shù)器,這樣的做法增加了
存儲空間的開銷
讳推。 - 每次復制都需要更新計數(shù)器,伴隨著加法和減法操作,這增加了
時間開銷
控乾。 - 引用計數(shù)器有一個嚴重的問題,即
無法處理循環(huán)引用
的情況。這是一條致命缺陷,導致在Java的垃圾回收器中沒有使用這類算法娜遵。
- 它需要單獨的字段存儲計數(shù)器,這樣的做法增加了
小結(jié)
- 引用計數(shù)算法,是很多語言的資源回收選擇,例如因人工智能而更加火熱的Python,它更是同時支持引用計數(shù)和垃圾收集機制。
- 具體哪種最優(yōu)是要看場景的,業(yè)界有大規(guī)模實踐中僅保留引用計數(shù)機制,以提高吞吐量的嘗試壤短。
- Java并沒有選擇引用計數(shù)器,是因為其存在一個基本的難題,也就是很難處理循環(huán)引用關(guān)系设拟。
- Python如何解決循環(huán)引用?
- 手動解除: 很好理解,就是在合適的時機,解除引用關(guān)系。
- 使用弱引用weakref,weakref是python提供的標準庫,旨在解決循環(huán)引用久脯。