1. 程式人生 > >java垃圾回收——工作機制

java垃圾回收——工作機制

一.如何確定物件沒有被引用

    第一種是遍歷堆上的物件找引用;

    第二種是遍歷堆疊或靜態儲存區的引用找物件

    第一種實現是“引用計數法”,第二種實現是“自適應”的垃圾回收技術

二.兩種實現的機制

引用計數法:當有引用連線至物件時,引用計數加1,當引用離開作用域或被置為null時,引用計數減1,這種方法有個缺陷,如果物件之間存在迴圈引用,可能會出現“物件應該被回收,但引用計數卻不為零”的情況。

“自適應”的垃圾回收技術(Java常用):

一種是“停止-複製”:理論上是先暫停程式的執行(所以它不屬於後臺回收模式),然後將所有存活的物件從當前堆複製到另一個堆,沒有被複制的全是垃圾。當物件被複制到新堆上時,它們是一個挨著一個的,所以新堆保持緊湊排列(這也是為什麼分配物件的時候“堆指標”只管依次往前移動)。然後就可以按前述方法簡單、直接地分配記憶體了。這將導致大量記憶體複製行為,記憶體分配是以較大的“塊”為單位的。有了塊之後,垃圾回收器就可以不往堆裡拷貝物件了,直接就可以往廢棄的塊裡拷貝物件了。

另一種是“標記-清掃”:它的思路同樣是從堆疊和靜態儲存區出發,遍歷所有的引用,進而找出所有存活的物件。每當它找到一個存活物件,就會給物件一個標記。這個過程中不會回收任何物件。只有全部標記完成時,沒有標記的物件將被釋放,不會發生任何複製工作,所以剩下的堆空間是不連續的,然後垃圾回收器重新整理剩餘的物件,使它們是連續排列的。

當垃圾回收器第一次啟動時,它執行的是“停止-複製”,因為這個時刻記憶體有太多的垃圾。然後Java虛擬機器會進行監視,如果所有物件都很穩定,垃圾回收器的效率降低的話,就切換到“標記-清掃”方式;同樣,Java虛擬機器會跟蹤“標記-清掃”效果,要是堆空間出現很多碎片,就會切換到“停止-複製”方式。這就是所謂的“自適應”技術。