垃圾收集器與記憶體分配策略
那些記憶體需要回收
什麼時候
如何回收
因為記憶體溢位、洩露問題,我們需要了解GC
判斷物件是否存活的演算法:
引用計數演算法
在物件中新增一個引用計數器,每當有一個地方引用他時,計數器+1,反之-1,任何時候,計數器=0就是不可能在被使用
實際上虛擬機器並不是通過引用計數演算法判斷物件是否存活
面試可以用到
可達性分析演算法
通過一系列稱為“GC Roots”的根作為起始節點集,從這些節點開始,根據引用關係向下搜尋,搜尋過程所走的路徑稱之為“引用鏈”,如果某個物件到GC Roots沒有任何引用鏈相連,證明這是不能再被使用
生存還是死亡
如果物件在進行可行性分析後發現沒有與GC Root相連線的引用鏈,它會被第一次標記,隨後篩選,條件是對此物件是否有必要執行finalize()方法,加入物件沒有覆蓋此方法或者finalize()方法被虛擬機器呼叫過,則視為沒必要執行
若被判斷有必要執行finalize()方法,那麼物件將會被放置在F-Queue佇列中
稍後收集器將對F-Queue中的物件進行第二次小規模標記,如果物件在finalize()中拯救自己,那麼在第二次標記之前將被移除“即將回收”的集合,否則將會被回收
finalize()能做的所有工作,try-catch能做的更好
1.1分代收集理論
絕大多數的物件都是潮生夕滅
熬過越多次的垃圾回收的物件越難以消亡
在新生代中,每次垃圾回收都會有大批的物件死去,但活下來的物件會逐步晉升到老年代中存放(好像是15次)
1.2標記清除演算法
先標記處所有需要回收的物件,統一回收未被標記的物件。
如何判定是否會標記,就在《生存還是死亡》一章有寫
缺點:執行效率不穩定,進行大量標記與清除,隨著物件增長而效率降低
記憶體空間碎片化問題
1.3標記複製演算法
分為伊甸園、from區,to區
to區永遠是空的
首先伊甸園標記清除,將獲得物件複製到to區,然後from區與to區互相交換
缺點:
浪費一半的空間
存活率較高的情況下,一直複製會導致效率變低
1.4、標記-整理演算法
通過分割槽空閒分配連結串列解決記憶體分配問題