標籤:
①首先說一下,GC裡邊在JVM當中是使用的ROOT演算法,ROOT演算法,什麼稱作為ROOT呢,就是說類的靜態成員,靜態成員就是static修飾的那種,是“根”的一個,根還包括方法中的成員變數,只有成員或對象不掛在根上,GC的時候就可能把他們搞掉,這裡提到的循環參考,就看這個循環參考是否掛在根上,如果掛在根上,如果這個根還被JVM的Java代碼所執行的話,就不會GC掉,如果說這個根已經被釋放掉了,這個對象不掛在跟上了,那個這個對象就會被GC掉。
②說一下根搜尋演算法,ROOTS,這個演算法,那些在Java裡會被認為是根呢,在我印象裡一般是static修飾的類成員,比如說靜態欄位,這種欄位引用的對象被稱為根,只要類在POOL區裡不被卸載,一直在堆裡,類對象只要沒被回收掉,他引用的對象就不會被GC。
③再說另一種情況,方法中的棧,棧中有他的棧成員 Integer a = XXX,當方法沒有被釋放,沒有出棧的時候,方法沒有被彈出的時候,那Integer a 所引用的對象也是不會被回收的,在什麼情況下回收呢,就是這個對象沒有掛在根上,就會被回收。
④我們回到標題的問題,這個循環參考是否被回收,就看這個循環參考是否掛在根上,A引用B,B引用A,A和B並沒有掛在某個記憶體元和根上,當他們的生命週期結束的時候,這兩個對象都有可能被回收。
⑥具體回收的機制,就比較複雜了,每次GC的時候,對要被回收的對象標記一次,比如說會有個計數器每次+1,+1,+1,每次GC的時候就+1一次,當對象達到預設值了,比如說好像15次吧,在新生帶建立的對象達到15次了就會被達到老年帶裡去,而老年代對象的回收的頻率和新生帶回收的頻率是不一樣的,可以仔細看中pool裡的分區,瞭解他們的運行機制。
註:JVM heap分區塊
Generation代 - YongGeneration/NewGeneration:新生代,在Eden/S0/S1的存活的對象。 - OldGeneration:老年代,在Tenured區存活的對象。
- PermanentGeneration:永久代。
Space 區 - Eden:伊甸園區,是新生代的一個區。
- Survivor:倖存區,屬於新生代,為了複製演算法的需要。一般分成大小相等的兩個區(S0/S1或者From/To)。 - Tenured:存放老年代的地區。
- Permanent:終身區。
:Hotspot 的 Heap 分區
對象A和B循環參考,最後會不會不被GC回收?-------關於Java的GC機制