這個確定對象是不是還有用 ,可以不可以扔掉 的算法
不止是Java在用, 主流的商用語言都是這個
基本思路:
以一些 GC Roots 作為跟, 向下搜索,
走過的路徑叫引用鏈
, 沒走到的,就是不可達
不可達的 就是 沒用了的
Java里面可作為GC Roots的
虛擬機棧/本地方法棧 中引用的對象
就是個線程在運行的方法里面用到的對象
方法區(qū)中 類靜態(tài)屬性/常量 引用的對象
就是是屬于類的static field 和final static field
被作為鎖的對象
反應JVM內部情況的對象
其他不回收的區(qū)域,可能對本區(qū)域引用的對象
4種引用
強
軟
空間不足一段時間后, 才會迫不得已回收它們
適合做緩存
弱
活不過下次回收,
這個在ThreadLocal 里面用到了,
既可以通過這個引用拿到threadLocal 對象,
如果其他強引用(來自各個線程的引用)不在了, 定義這個static threadLocal 的class里面對 threadLocal 的引用 不會阻止其被回收
虛
作用是 回收時可以得到通知
finalize()
這個方法沒啥用 ,不要用
某對象 如果 沒在引用鏈
上,就是是死的
會看它是否有覆蓋finalize
方法,
如果有寫finalize
方法,并且沒執(zhí)行過
就會放到一個F-Queue隊列里面,
有一個優(yōu)先級很低的線程, 過一會兒來運行, 但是不保證給你運行完, 如果花費太大就算了
如果在
finalize
里面寫的 xxx=this 再給建立一個引用 把他救活 是可以的
但是只能這么做一次, 下次回收 發(fā)現(xiàn)又沒有引用的話
這個對象finalize
已經被執(zhí)行過了, 是不會被再次執(zhí)行的
二次標記:
指的是 finalize
里面是可以救 這個對象的
通過再次建立引用, 把這個對象移出 待回收 的集合
方法區(qū) 的回收
又叫類卸載
虛擬機規(guī)范里面, 沒有要求 一定要對 方法區(qū)進行回收, 確實也有收集器(11的ZGC)沒有類卸載
類卸載, 條件苛刻,收效甚微
但是,現(xiàn)在動態(tài)代理 CGLib字節(jié)碼框架,動態(tài)生成類,OSGI頻繁自定義類加載器, JVM比較小 可以類卸載
以下條件是 類不再被需要,可以被卸載的 必要條件(非充分):
- 沒實例了
- 類加載器 沒了
- 對應的Class對象 沒了
以上↑ 是必要條件
實際上, 什么樣的情況運行類卸載 , 可通過參數(shù)自己控制
可以查看 類加載 類卸載信息