1. 程式人生 > >Java垃圾回收器

Java垃圾回收器

引用記數:一種簡單但速度很慢的技術,每個物件都含有一個引用計數器,當引用連線值物件時,引用記數加1,;當引用離開作用域或被置為null時,引用記數減1,遍歷所有物件,管理引用計數的開銷不大,但這項開銷在整個程式生命過程中持續發生。
缺陷在於如果物件之間存在迴圈引用,可能出現"物件應該被被回收,但引用記數不為0",定位互動引用的的物件組所需工作量極大。常用來說明垃圾收集的工作方式,未被應用於任何一種Java虛擬機器中。

在一些更快的模式中,垃圾回收器並非基於引用計數技術,它們依據的思想是:對任何活的物件,一定能追蹤到其存活的堆疊或靜態儲存區之中的引用,這種方式確保了你訪問過的物件必須是活的。這就解決了"互動自引用的物件組"的問題,
在這種方式下,Java虛擬機器將採用一種自適應的垃圾回收技術。
有一種做法名為"停止--複製",即先暫停程式執行,然後將左右存活的物件從當前堆複製到另一個堆,沒有被複制的全是垃圾。當物件被複制到新堆,它們是一個挨著一個的,所以新堆保持緊湊排列。對於這種"複製回收器"而言,效率會降低,首先得有兩個堆,維護比實際需要多一倍的時間,
其次在於複製,專案穩定後很少甚至不產生垃圾,儘管如此,複製回收器仍然將所有的記憶體自一處複製到另一處,這很浪費。為了避免這種浪費,一些Java虛擬機器會進行檢查:要是沒有新垃圾產生,就會轉換到另一種工作模式,稱為"標記--清掃"。
"標記--清掃"的思路同樣是從堆疊和 靜態儲存區出發,遍歷所有的引用,進而找出所有存活的物件,當找到一個存活物件,就會給物件設一個標記,這個過程不會回收任何物件,只有當標記工作全部完成後,才會開始清理工作,沒有標記的物件將被釋放,不會發生任何重複動作。所以剩下的
堆空間是不連續的垃圾回收器通過重新整理剩下的物件得到連續的堆空間。
如果所有的物件都很穩定,垃圾回收器的相率降低的話,就切換到"標記--清掃"方式,虛擬機器會跟蹤"標記--清掃"的效果,如果堆空間出現很多碎片,就切換回"停止--複製"方式,這邊是"自適應技術"。