本章開始學習垃圾回收的過程,垃圾回收的過程首先就是要確定對象是否是垃圾對象,如果是垃圾對象,垃圾回收器才會進行回收。垃圾回收主要又兩種算法:引用計數算法和可達性分析算法。
一、引用計數算法
引用計數算法就是在對象中添加了一個引用計數器,當有地方引用這個對象時,引用計數器的值就加1,當引用失效的時候,引用計數器的值就減1。當引用計數器的值為0時,jvm就開始回收這個對象。
簡單的來說,在JVM中的棧中,如果棧幀中指向了一個對象,那么堆中的引用計數器的值就會加1,當棧幀這個指向null時,對象的引用計數器就減1。
這種方法雖然很簡單、高效,但是JVM一般不會選擇這個方法,因為這個方法會出現一個問題:當對象之間相互指向時,兩個對象的引用計數器的值都會加1,而由於兩個對象時相互指向,所以引用不會失效,這樣JVM就無法回收。
二、可達性分析算法
針對引用計數算法的BUG,JVM采用了另一種方法:定義一個名為"GC Roots"的對象作為起始點,這個"GC Roots"可以有多個,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的,即可以進行垃圾回收。
在上圖中可以看到,如果時選用引用計數算法,object5, object6, object7之間互相引用,所以無法被回收。但是如果選用了可達性分析算法,雖然他們之間時相互引用,但是他們沒有任何引用鏈和GC Roots連接,所以是可回收對象。
GC Roots對象一般包括有:1.虛擬機棧(棧幀中本地變量表)中引用的對象;2.方法區中類靜態屬性引用的對象;3.方法區中常量引用的對象;4.本地方法棧中JNI(Native方法)引用的對象。