①首先說一下,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分區塊
- PermanentGeneration:永久代。
Space 區
- Survivor:幸存區,屬於新生代,為了復制算法的須要。一般分成大小相等的兩個區(S0/S1或者From/To)。
- Permanent:終身區。

