1. 程式人生 > >GC是什麼?為什麼要有GC?

GC是什麼?為什麼要有GC?

GC是垃圾收集的意思,記憶體處理是程式設計人員容易出現問題的地方,

忘記或者錯誤的記憶體回收會導致程式或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測物件是否超過作用域從而達到自動回收記憶體的目的,

Java語言沒有提供釋放已分配記憶體的顯示操作方法。Java程式設計師不用擔心記憶體管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以呼叫下面的方法之一:System.gc()或Runtime.getRuntime().gc(),但JVM可以遮蔽掉顯示的垃圾回收呼叫。 


垃圾回收可以有效的防止記憶體洩露,有效的使用可以使用的記憶體。垃圾回收器通常是作為一個單獨的低優先順序的執行緒執行

不可預知的情況下對記憶體堆中已經死亡的或者長時間沒有使用的物件進行清除和回收,程式設計師不能實時的呼叫垃圾回收器對某個物件或所有物件進行垃圾回收。

在Java誕生初期,垃圾回收是Java最大的亮點之一,因為伺服器端的程式設計需要有效的防止記憶體洩露問題,然而時過境遷,如今Java的垃圾回收機制已經成為被詬病的東西。移動智慧終端使用者通常覺得iOS的系統比Android系統有更好的使用者體驗,其中一個深層次的原因就在於Android系統中垃圾回收的不可預知性。


採用“分代式垃圾收集”。這種方法會跟Java物件的生命週期將堆記憶體劃分為不同的區域,在垃圾收集過程中,可能會將物件移動到不同區域: 
- 伊甸園(Eden):這是物件最初誕生的區域,並且對大多數物件來說,這裡是它們唯一存在過的區域。 
- 倖存者樂園(Survivor):從伊甸園倖存下來的物件會被挪到這裡。 
- 終身頤養園(Tenured):這是足夠老的倖存物件的歸宿。年輕代收集(Minor-GC)過程是不會觸及這個地方的。當年輕代收集不能把物件放進終身頤養園時,就會觸發一次完全收集(Major-GC),這裡可能還會牽扯到壓縮,以便為大物件騰出足夠的空間。

與垃圾回收相關的JVM引數:

·        -Xms / -Xmx —堆的初始大小 / 堆的最大大小

·        -Xmn — 堆中年輕代的大小


補充:

Java是由C++發展來的。

它擯棄了C++中一些繁瑣容易出錯的東西。其中有一條就是這個GC。

寫C/C++程式,程式設計師定義了一個變數,就是在記憶體中開闢了一段相應的空間來存值。記憶體再大也是有限的,所以當程式不再需要使用某個變數的時候,就需要釋放這個記憶體空間資源,好讓別的變數來用它。在C/C++中,釋放無用變數記憶體空間的事情要由程式設計師自己來解決。就是說當程式設計師認為變數沒用了,就應當寫一條程式碼,釋放它佔用的記憶體。這樣才能最大程度地避免記憶體洩露和資源浪費。

但是這樣顯然是非常繁瑣的。程式比較大,變數多的時候往往程式設計師就忘記釋放記憶體或者在不該釋放的時候釋放記憶體了。而且釋放記憶體這種事情,從開發角度說,不應當是程式設計師所應當關注的。程式設計師所要做的應該是實現所需要的程式功能,而不是耗費大量精力在記憶體的分配釋放上。

Java有了GC,就不需要程式設計師去人工釋放記憶體空間。當Java虛擬機發覺記憶體資源緊張的時候,就會自動地去清理無用變數所佔用的記憶體空間。當然,如果需要,程式設計師可以在Java程式中顯式地使用System.gc()來強制進行一次立即的記憶體清理。

因為顯式宣告是做堆記憶體全掃描,也就是 Full GC,是需要停止所有的活動的(Stop The World Collection),你的應用能承受這個嗎?而其顯示呼叫System.gc()只是給虛擬機器一個建議,不一定會執行,因為System.gc()在一個優先順序很低的執行緒中執行。