java垃圾回收機制的工作特征解析

時間:2022-03-30 03:38:00

導語:java垃圾回收機制的工作特征解析一文來源于網友上傳,不代表本站觀點,若需要原創文章可咨詢客服老師,歡迎參考。

java垃圾回收機制的工作特征解析

關鍵詞:java虛擬機;垃圾收集;垃圾收集器

摘要:垃圾收集是java語言區別于其他程序設計語言的一大特色。但是目前多數的java書籍有關垃圾收集的內容幾乎沒有或只做了非常簡單的介紹。本文從多個方面分析了java的垃圾回收機制,使學習者能夠對該機制產生一個全面的認識。

java的堆是一個運行時數據區,類的實例從中分配空間,堆中存儲著正在運行的應用程序建立的所有對象。垃圾回收是一種動態存儲管理技術,它自動釋放不再被程序引用的對象,按照特定的垃圾收集算法來實現資源的自動回收。一般來說,堆的回收是由垃圾收集器負責的,盡管jvm規范并不要求特殊的垃圾回收技術,但是由于內存的有限性,jvm在實現的時候都有一個由垃圾回收所管理的堆。

一、垃圾回收及其意義

正在運行的程序中被引用的對象處于存活狀態,不再被引用的對象就是通常所說的垃圾,查找并釋放垃圾對象所占用內存空間的過程稱為垃圾收集。

在java中,當沒有對象引用指向分配給某個對象的內存時,該內存便成為垃圾。jvm的一個系統級線程會自動釋放該內存。除了釋放沒有用的對象,垃圾收集也可以清除內存記錄碎片。由于創建對象和釋放對象所占的內存空間,內存會出現碎片。碎片整理將所占用的堆內存移到堆的一端,將整理出的內存分配給新的對象。

垃圾收集機制有如下優點:首先,它能使編程效率提高。在沒有垃圾收集機制的時候,可能要花許多時間來解決一個難懂的存儲器問題,而使用java的垃圾收集機制可大大節省時間。其次,它能避免內存滲漏體的產生,保護程序的完整性,垃圾收集是java語言安全性策略的一個重要組成部分。

垃圾收集的一個潛在的缺點是它的開銷影響程序性能。java虛擬機必須追蹤運行程序中有用的對象,并且釋放沒用的對象。這一個過程需要花費處理器的時間。其次垃圾收集算法的不完備性,許多垃圾收集算法不能保證100%收集到所有的廢棄內存。

二、垃圾的判斷標準與回收方法

垃圾收集器判斷一個對象的內存空間是否無用的標準是:如果該對象不能再被程序中任何一個“活動的部分”所引用,此時我們說,該對象的內存空間已經無用。所謂“活動的部分”,是指程序中某部分參與程序的調用,尚未執行完畢。

常見的一種情況是,當內存中的一個對象不再被任何變量引用的時候,這個對象就成為內存中的垃圾。java的垃圾收集機制可以發現這種沒有任何引用的對象,并在適當時候回收該對象所使用的內存。例如:

integeri=newinteger(0);

...

i=null;//此時,前面integer(0)所產生的對象就成為垃圾。

具體的說,一個變量或對象是否垃圾可遵循如下規則進行判斷:

(一)變量出了作用域就成為垃圾。

(二)變量名失去指向就會變成垃圾。

(三)對象失去變量名的指向同樣變成垃圾。

(四)匿名對象本身就是垃圾。

垃圾收集在多數情況下是自動進行的,也可使用system.gc()方法提醒jvm檢查有沒有要回收的對象,它不明確的指定jvm去回收哪個對象。垃圾收集是jvm上優先級最低的線程,調用system.gc()在多數時候并不馬上進行垃圾收集。

項目中最好能手動釋放資源,jdk源碼里流的部分的close()方法,其實底層都是手動釋放:

if(inputstream!=null)

{

inputstream.invalidate();

inputstream=null;

}

在對性能要求比較高的項目中,如果一個對象用完后要將其引用變量指向null。

三、java垃圾收集工作的的特點

經過前面的分析,可以發現java的垃圾回收有以下特點:

(一)垃圾收集線程作為低優先級的線程運行,但在系統可用內存量過低的時候,可能會突發地執行來釋放內存資源。垃圾收集器不可以被強制執行,但程序員可以通過調用system.gc()方法來建議執行垃圾收集器。

(二)不能保證一個無用的對象一定會被垃圾收集器收集,也不能保證垃圾收集器在一段java代碼中一定會執行,因此在程序執行過程中被分配出去的內存空間可能會一直保留到該程序執行完畢。由此可見,徹底地根絕內存滲漏體的產生也是不可能的。

(三)可以通過將對象的引用變量置為null來通知垃圾收集器來收集該對象。但如果該對象連接有事件監聽器,那它還是不能被收集。所以在將引用變量置為null之前,應首先除去監聽器。

(四)每一個對象都有一個finalize()方法,這個方法是從object類繼承的。finalize()方法用來回收內存以外的系統資源,書寫程序時該方法的順序和方法的實際調用順序是不相干的,這是finalize()方法的特點。

java語言允許程序員為任何對象添加finalize()方法,該方法會在垃圾收集器回收對象之前被調用。但不要過分依賴該方法對系統資源的回收,因為該方法調用后的執行結果是不可預知的。

(五)當一個方法執行完畢,其中的局部變量就會超出使用范圍,此時可以被當作垃圾收集,以后再調用該方法時,其中的局部變量便會被重新創建。

結束語:

對于java的垃圾回收工作,在寫程序時要考慮以下準則:

(一)不要試圖去假定垃圾收集發生的時間,這一切都是未知的。

(二)java提供了一些用于垃圾收集的類,而且提供了建議進行垃圾收集的方法——system.gc(),但這是一個不確定的方法。java并不保證每次調用該方法就一定能夠啟動垃圾收集。

(三)挑選適合自己的垃圾收集器。如果系統沒有特殊和苛刻的性能要求,可以采用jvm的缺省選項。否則可以考慮使用有針對性的垃圾收集器,例如增量收集器適合實時性要求高的系統。具有較高的配置,有較多閑置資源的系統可以考慮使用并行標記/清除收集器。

(四)應盡早釋放無用對象。引用變量在退出活動域后要置為null,通知垃圾收集器來收集該對象,還要注意引用的對象是否被監聽,如果有,要先去掉監聽器。

java開發人員可以不重視jvm中堆內存的分配和垃圾收集,但是充分理解java的這一特性可以讓我們更有效地利用資源。