這篇博客是對 http://www.cnblogs.com/sunniest/p/4575144.html 學習和整理。
垃圾回收算法要做的兩件事:1.定位無用對象 2.回收對象占用空間
對于定位無用對象,有兩種算法:引用計數算法,根搜索算法。
引用算法通過統計這個引用的使用情況來決定這個對象引用要不要回收,注意下他的優缺點。
根搜索通過將所有的引用關系生成圖來產生無關節點的方式來找到回收節點(值得注意的是只有以GC root為根的圖才是有效的,我的理解是森林中只有一棵樹有效,其他樹都是無用節點),注意下可以作為root的對象(方法區中的靜態屬性,常量,本地變量表和native對象)。
對于回收,有以下方法:清除,整理,copying以及比較復雜的generation算法
清除算法直接清除無用對象,會產生內存碎片,
整理算法在句柄和句柄表的支持下對清除以后的內存進行整理,但是由于使用了句柄和句柄表處理時間會較長
copying算法并不直接尋找無用對象,而是尋找活動對象,將活動對象復制到另一個區中,再直接清空當前的對象區。
generation算法需要另外拿出來講。
generation算法:分代算法
generation基于這樣一個事實:不同的對象的生命周期是不一樣的,將對象分成三代,新生代Young,年老代Tenured和持久代Perm
持久代用于存放靜態文件,如Java類、方法等,其余的對象都是先裝入新生代,滿足一定條件(新生代的存活區唄裝滿)以后才會裝入年老代。
在分代算法中,GC集中在新生代,稱為Scavenge GC,但只有Full GC才能處理年老代和持久代,所以full gc的觸發條件中就有持久代被裝滿和年老代被裝滿,還有system.gc(),上一次GC之后Heap的各域分配策略動態變化(這個表示不是很懂)。
在新生代和年老代的不同的收集器算法中:serial和Par以及CMS三種
GC不是萬能的,需要開發者自己處理的部分
1.靜態集合類像HashMap、Vector等的使用最容易出現內存泄露
2.各種連接,數據庫連接,網絡連接,IO連接等沒有顯示調用close關閉,不被GC回收導致內存泄露。
3.監聽器的使用,在釋放對象的同時沒有相應刪除監聽器的時候也可能導致內存泄露。