垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收?


一、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收?

  1對於GC來說,當程序員創建對象時,GC就開始監控這個對象的地址、大小以及使用情況。

       通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC確定一些對象為"不可達"時,GC就有責任回收這些內存空間。

     2、可以。程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范並不保證GC一定會執行。

二、這里我們詳細了解一下System.gc()的工作原理:

 Java中的內存分配是隨着new一個新的對象來實現的,這個很簡單,而且也還是有一些可以“改進”內存回收的機制的,其中最顯眼的就是這個System.gc()函數。

  乍一看這個函數似乎是可以進行垃圾回收的,可事實並不是那么簡單。
  其實這個gc()函數的作用只是提醒虛擬機:程序員希望進行一次垃圾回收。但是它不能保證垃圾回收一定會進行,而且具體什么時候進行是取決於具體的虛擬機的,不同的虛擬機有不同的對策。

  那么下一個問題就是:gc()進行回收的准則是什么?也就是說什么樣的對象可以被回收?
簡單來說就是:沒有被任何可達變量指向的對象。這里的可達是我發明的……意思就是能夠找到的,那什么樣的是不可達的呢?
比如說:

1 a.v = b;
2 b.v = c;
3 /*
4  *Watch out !
5  */
6 a.v = d;

看一下這段代碼:
第一行:對象a的變量v指向了對象b
第二行:對象b的變量v指向了對象c
第六行:對象a的變量v指向了變量d。
這個時候,雖然變量c指向的對象有c以及b.v指向它,但是它們都已經不可達了,為什么?因為唯一可以找到它們的是a.v,但是現在a.v指向了d,所以他們就是不可達的了。

理由也很直觀:沒有任何可達變量指向你,你還有活下去的理由嗎?你就算活下去誰能找得到你呢?

所以說,C++中將釋放了的指針置為null的習慣要保留到Java中,因為這有可能是你釋放內存的唯一途徑。

最后的箴言:不要頻繁使用gc函數。
我的建議是:保持代碼健壯(記得將不用的變量置為null),讓虛擬機去管理內存。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM