Garbage Collection 垃圾收集,簡稱GC。Java中GC的對象是堆空間和永久區。
複製代碼
概念:在標記清除的的基礎上改進python
原理:將原有的內存空間分爲兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中的存活對象複製到未使用的內存塊中,以後,清除正在使用的內存塊中的全部對象,交換兩個內存的角色,完成垃圾回收算法
缺點:看圖bash
優勢:ide
一、優秀的吞吐量: GC 標記 - 清除算法消耗的吞吐量是搜索活動對象(標記階段)所花費的時間和搜索總體 堆(清除階段)所花費的時間之和。
另外一方面,由於 GC 複製算法只搜索並複製活動對象,因此跟通常的 GC 標記 - 清除算 法相比,它能在較短期內完成 GC。也就是說,其吞吐量優秀。
二、高速分配:GC 複製算法不使用空閒鏈表。這是由於分塊是一個連續的內存空間。比起 GC 標記 - 清除算法和引用計數法等使用空閒鏈表的分配,GC 複製算法明顯快得多。
三、不會發生碎片化
複製代碼
總結的時候我以爲仍是引入一下分代思想比較清晰post
依據對象的存活週期進行分類,短命對象歸爲新生代,長命對象歸爲老年代。性能
根據不一樣代的特色,選取合適的收集算法優化
問:GC算法中 怎麼判斷這個對象是不是垃圾對象,是根據可觸及性來判斷的,那麼什麼是可觸及性呢。ui
答:this
還有一個概念也不能斷定這個對象是垃圾對象就是 --可復活的spa
一旦全部引用被釋放,就是可復活狀態,由於在finalize()中可能復活該對象
複製代碼
不過這個通常不使用:
避免使用finalize(),操做不慎可能致使錯誤。
優先級低,什麼時候被調用, 不肯定
什麼時候發生GC不肯定
可使用try-catch-finally來替代它經驗:避免使用finalize(),操做不慎可能致使錯誤。
優先級低,什麼時候被調用, 不肯定
什麼時候發生GC不肯定
可使用try-catch-finally來替代它
複製代碼
這裏你能夠代碼試下
public class CanReliveObj {
public static CanReliveObj obj;
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("CanReliveObj finalize called");
obj=this;
}
@Override
public String toString(){
return "I am CanReliveObj";
}
public static void main(String[] args) throws
InterruptedException{
obj=new CanReliveObj();
obj=null; //可復活
System.gc();
Thread.sleep(1000);
if(obj==null){
System.out.println("obj 是 null");
}else{
System.out.println("obj 可用");
}
System.out.println("第二次gc");
obj=null; //不可復活
System.gc();
Thread.sleep(1000);
if(obj==null){
System.out.println("obj 是 null");
}else{
System.out.println("obj 可用");
}
}
複製代碼
Java中一種全局暫停的現象,全局停頓,全部Java代碼中止,native代碼能夠執行,但不能和JVM交互,多半因爲GC引發 Dump線程、 死鎖檢查、堆Dump。
GC時爲何會有全局停頓? 類比在聚會時打掃房間,聚會時很亂,又有新的垃圾產生,房間永遠打掃不乾淨,只有讓你們中止活動了,才能將房間打掃乾淨。
危害:長時間服務中止,沒有響應,遇到HA系統,可能引發主備切換,嚴重危害生產環境。