1、為什么要進行垃圾回收:
在C++中,對象所占的內存在程序結束運行之前一直被占用,在明確釋放之前不能分配給其它對象;而在Java中,當沒有對象引用指向原先分配給某個對象 的內存時,該內存便成為垃圾。 垃圾回收能自動釋放內存空間,減輕編程的負擔,JVM的一個系統級線程會自動釋放該內存塊。垃圾回收意味着程序不再需要的對象是"無用信息",這些信息將被丟棄。當一個對 象不再被引用的時候,內存回收它占領的空間,以便空間被后來的新對象使用。事實上,除了釋放沒用的對象,垃圾回收也可以清除內存記錄碎片。由於創建對象和垃圾回收器釋放丟棄對象所占的內存空間,內存會出現碎片。碎片是分配給對象的內存塊之間的空閑內存洞。碎片整理將所占用的堆內存移到堆的一端,JVM將整理出的內存分配給新的對象。
2、如何進行垃圾回收:
Java語言規范沒有明確地說明JVM使用哪種垃圾回收算法,但是任何一種垃圾回收算法一般要做2件基本的事情:(1)發現無用信息對象;(2)回收被無用對象占用的內存空間,使該空間可被程序再次使用。
大多數垃圾回收算法使用了根集(root set)這個概念;所謂根集就是正在執行的Java程序可以訪問的引用變量的集合(包括局部變量、參數、類變量),程序可以使用引用變量訪問對象的屬性和 調用對象的方法。垃圾回收首先需要確定從根開始哪些是可達的和哪些是不可達的,從根集可達的對象都是活動對象,它們不能作為垃圾被回收,這也包括從根集間 接可達的對象。
3、對於特殊區域的垃圾回收(比如調用cc語言中的malloc()函數進行空間的分配那么垃圾回收機制就不能回收這類特殊空間): 之所以要使用finalize(),是存在着垃圾回收器不能處理的特殊情況。假定你的對象(並非使用new方法)獲得了一塊“特殊”的內存區域,由於垃圾 回收器只知道那些顯示地經由new分配的內存空間,所以它不知道該如何釋放這塊“特殊”的內存區域,那么這個時候java允許在類中定義一個由 finalize()方法
4、觸發GC(Garbage Collector)的條件:
JVM進行次GC的頻率很高,但因為這種GC占用時間極短,所以對系統產生的影響不大。更值得關注的是主GC的觸發條件,因為它對系統影響很明顯。總的來說,有兩個條件會觸發主GC:
1)當應用程序空閑時,即沒有應用線程在運行時,GC會被調用。因為GC在優先級最低的線程中進行,所以當應用忙時,GC線程就不會被調用,但以下條件除外。
2)Java堆內存不足時,GC會被調用。 當應用線程在運行,並在運行過程中創建新對象,若這時內存空間不足,JVM就會強制地調用GC線程,以便回收內存用於新的分配。若GC一次之后仍不能滿足 內存分配的要求,JVM會再進行兩次GC作進一步的嘗試,若仍無法滿足要求,則 JVM將報“out of memory”的錯誤,Java應用將停止。
5、減少GC開銷的措施:
- 不要顯示的調用System.gc()
- 盡量減少臨時對象的使用
- 對象不用的時候最好顯示置空
- 盡量使用StringBuffer,不實用String累加字符串(String的特性有關)
- 能使用基本數據類型就不要使用封裝類
- 盡量減少靜態對象變量的使用
6、注意:
- GC的回收時間是不確定的,即使你顯示的調用的System.gc()。因為和線程優先級有關
- 使用了finalize()方法之后,GC是在這個方法執行之后的下一次進行垃圾的回收。
