-
前言
總所周知,jvm的垃圾收集算法通常包括標記、清除、整理三個階段,最近在看了有關於垃圾收集的標記算法,記錄一下本身的理解。算法
垃圾收集中標記算法有兩種:一種是引用計數法,一種是根搜索算法。jvm
-
引用記數法
引用計數法很是容易理解,jvm爲每個對象設立一個引用計數器,當該對象被引用時,計數器就加一,引用取消時則減一。spa
當jvm開始gc時,jvm判斷該對象的引用計數器是否爲0,若爲0則標記爲可清除對象。指針
引用計數器有個致命的缺點是沒法解決循環依賴問題,這也致使這個算法被棄用。對象
以下圖所示,當對象A中有對B的引用,對象B中也有對A的引用,二者之間造成循環依賴。blog
除此以外,還有一個point引用了對象A,此時程序中還有point這個指針可以使程序到達這兩個對象,內存
一旦point引用取消,咱們就會丟失對這兩個對象的控制,同時引用計數器未到達0,因此對象一直存在在堆中,JVM不能進行回收,今後形成內存泄漏。class
-
根搜索算法
根搜索算法是目前大部分JVM所使用的標記算法。內存泄漏
根搜索算法會以根對象集合中的根對象出發,進行自上往下的搜索,與根對象直接鏈接或間接鏈接的對象均可以被搜索。搜索
當JVM沒法到達某個對象時,它會被標記爲可清除對象。
根對象集合指的是:
- JAVA棧中的對象引用
- 本地方法棧的對象引用
- 運行時常量池中的對象引用
- 方法區中的類靜態屬性的對象引用
- 類對應的惟一數據類型的Class對象(這句話有點抽象,實際上每一個類都有一個Class對象用於表示這個類在運行時被JVM加載的相關信息,如類名、方法、屬性等)
可使用ClassName.class、實例化對象.class、Class.forName(),獲取該類的Class對象
根搜索算法的過程