Jvm知識學習(四)-GC算法與種類

一,GC的概念
Garbage Collection 垃圾收集
1960年 List 使用了GC
Java中,GC的對象是堆空間和永久區

二,GC算法
根 對象:
(1)棧中引用的對象
(2)方法區中靜態成員或者常量引用的對象(全局對象)
(3)JNI方法棧中引用對象
1,引用計數法
老牌垃圾回收算法
通過引用計算來回收垃圾
使用者 :COM,ActionScript3,Python 
原理:引用計數器的實現很簡單,對於一個對象A,只要有任何一個對象引用了A,則A的引用計數器就加1,當引用失效時,引用計數器就減1。只要對象A的引用計數器的值爲0,則對象A就不可能再被使用。

引用計數法的問題 :
(1)引用和去引用伴隨加法和減法,影響性能
(2)很難處理循環引用


2,標記清除
原理:標記-清除算法是現代垃圾回收算法的思想基礎。標記-清除算法將垃圾回收分爲兩個階段:標記階段和清除階段。一種可行的實現是,在標記階段,首先通過根節點,標記所有從根節點開始的可達對象。因此,未被標記的對象就是未被引用的垃圾對象。然後,在清除階段,清除所有未被標記的對象。


3,標記壓縮
原理:標記-壓縮算法適合用於存活對象較多的場合,如老年代。它在標記-清除算法的基礎上做了一些優化。和標記-清除算法一樣,標記-壓縮算法也首先需要從根節點開始,對所有可達對象做一次標記。但之後,它並不簡單的清理未標記的對象,而是將所有的存活對象壓縮到內存的一端。之後,清理邊界外所有的空間。


4,複製算法
與標記-清除算法相比,複製算法是一種相對高效的回收方法
不適用於存活對象較多的場合 如老年代
原理:將原有的內存空間分爲兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中的存活對象複製到未使用的內存塊中,之後,清除正在使用的內存塊中的所有對象,交換兩個內存的角色,完成垃圾回收 。


複製算法的最大問題是:空間浪費 整合標記清理思想

如下圖:15M是全部空間內存,其中由於複製算法所浪費的空間是1536K,所以total爲13824K。


分代思想:
依據對象的存活週期進行分類,短命對象歸爲新生代,長命對象歸爲老年代。
根據不同代的特點,選取合適的收集算法
少量對象存活,適合複製算法 (新生代)
大量對象存活,適合標記清理或者標記壓縮 (老年代)

GC算法總結:
引用計數 :沒有被Java採用 
標記-清除 ,標記-壓縮:老年代 
複製算法 :新生代

三,可觸及性
可觸及的 :從根節點可以觸及到這個對象 
可復活的 :一旦所有引用被釋放,就是可復活狀態,因爲在finalize()中可能復活該對象 
不可觸及的 :
(1)在finalize()後,可能會進入不可觸及狀態 
(2)不可觸及的對象不可能復活
(3)可以回收
示例:


經驗總結:
避免使用finalize(),操作不慎可能導致錯誤。
優先級低,何時被調用, 不確定
何時發生GC不確定
可以使用try-catch-finally來替代它

四,Stop-The-World
說明:
Java中一種全局暫停的現象
全局停頓,所有Java代碼停止,native代碼可以執行,但不能和JVM交互
多半由於GC引起 :
Dump線程
死鎖檢查
堆Dump

GC時爲什麼會有全局停頓?
類比在聚會時打掃房間,聚會時很亂,又有新的垃圾產生,房間永遠打掃不乾淨,只有讓大家停止活動了,才能將房間打掃乾淨。

危害
長時間服務停止,沒有響應
遇到HA系統,可能引起主備切換,嚴重危害生產環境。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章