淺談Java記憶體回收

來源:互聯網
上載者:User

記憶體回收,是java同c++的一個重大區別,也是編寫java程式不用指標的一個重要保證。在c++中,當一個對象不再有價值的時候,我們需要手動的清除這個對象,以釋放空間。在java中,這個工作由記憶體回收行程自動完成,程式員不必考慮難纏的對象回收問題。

一、記憶體回收的好處: 
記憶體回收使程式員從釋放記憶體的重擔中解脫,可以把更多的精力放在編程和邏輯上,提高了效率。 
記憶體回收保證了程式的正常運行,不會出現如c++中的因為對象忘記釋放而產生的記憶體泄露等諸多問題。

二、記憶體回收的基本方法:
所有的記憶體回收演算法都要做兩件事:檢測出垃圾對象和刪除垃圾對象並把堆空間歸還程式。
1.引用計數器:
在堆中的每個對象都有一個對應的計數器,當建立一個對象並將此對象的引用指定到一個變數的時候,引用計時器為1。當此對象被其他對象引用的時候,計數器+1,其他對象對此對象的引用取消,計數器-1。當計數器為0的時候,這個對象就已經是沒有被引用的了,記憶體回收行程就可以收集它了。
引用計數器被用在早期的記憶體回收策略中,計數器不能處理循環參考(父物件引用子物件,自對象也引用父物件,這兩個對象採用引用計數器不能被收集)。
2.跟蹤收集器:
跟蹤收集器將堆中的對象及引用映射成一個圖。對象為圖的節點,對象間的引用為圖中的邊。
記憶體回收從跟節點開始,通過曆遍這個圖找出圖中的孤立節點,即為垃圾對象。

三、記憶體回收處理堆碎塊的策略:
當一個對象被回收後,它的堆空間歸還程式,當對個對象被回收後,就會出現一個問題,堆中的空間不連續了。如此,當建立一個新對象的時候,可能由於堆中前面的空白空間不夠而不得不繼續分配後面連續的空間,這樣不僅浪費堆空間,而且可能造成對空間不足,記憶體溢出。
一般情況下,採用以下幾種回收器來解決這個問題:
1.壓縮收集器:
壓縮收集器把活動的對象移動到堆的一段,那麼在堆的另一端就好出現連續的大片空白空間。

2.拷貝收集器:
拷貝收集器將使用中的物件拷貝到一個新的地區,在拷貝過程中,這些活動的對象將被緊湊的放在新的地區,這樣就消除了舊地區的空隙。當新地區滿的時候,再將使用中的物件拷貝到舊地區,如此往複。
由於對象拷貝需要程式停止運行,地區中對象的拷貝很耗時,會影響程式的正常運行。


3.按代收集器:
在程式中大對象有這樣的特點,大部分對象的生命週期比較短,小部分的對象生命週期比較長。考慮到這個原因,可以把堆分成若干個子堆,每個子堆稱為一代(由低到高一代,二代三代……)。把生命周短的對象放在底代中,生命週期長的放在高代中。這樣,底代的對象收集會更頻繁一點,高代的則收集頻率少一點,保證了收集的效率。在每次收集的時候,如果發現這個代中的對象是活動的,則把它放到更高的代中,否則收集。
4.自適應收集器:
自適應收集會根據堆中的對象情況選擇適當的收集器或調整收集器的參數,以實現更高的效率。

以上即是java記憶體回收的基本方法。如有不足和錯誤歡迎大家指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.