深入理解JAVA虛擬機學習筆記4——垃圾收集器概述

時隔這麼久,這個系列又和大家見面了,感謝支持我的朋友,只要能給大家帶來一點點收穫,我真的時發自內心的開心!

今天先簡單瞭解一下虛擬機的垃圾收集器。

前面已經介紹過了,程序計數器,虛擬機棧和本地方法棧是屬於線程私有區域,這三個區域分配和回收都是確定的,方法和線程結束後,內存自認而然就回收了。

而Java堆和方法作爲公共區域回收則比較複雜,垃圾收集器所關注也是這兩個部分的內存。

但是如何判斷哪些對象應該被回收呢?

比較簡單的是引用計數算法:給對象增加一個計數器,多一個地方引用此對象,該對象的計數器就加1;少一個對此對象的引用,計數器就減1。

這種方式的優點是判斷效率高,但是也有一個嚴重的缺點:存在對象之間循環引用的問題。

比如在一段程序中,有如下引用方式,objA.instacce=objB和objB.instacce=objA,這種將不會被回收。

所以主流的Java虛擬機裏面並沒有使用這種方式,而是採用了另外一種方式——可達性分析算法。

基本思想:通過一系列的稱爲“GC Roots”的對象作爲起始點,從這些節點開始向下搜索,搜索所 走過的路徑稱爲引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連 (用圖論的話來說,就是從GC Roots到這個對象不可達)時,則證明此對象是不可用的。(摘自《深入理解JAVA虛擬機》)

如下圖所示,object5,object6, object7沒有道GC Root對象的引用鏈,是可以被回收的。注意,這裏是可以被回收,這時並不一定會被立刻回收。

那麼,什麼樣的對象可以被選作爲GC Roots對象呢,主要有以下四類。

既然提到了”引用”,那麼JAVA中引用是怎麼定義的呢?

傳統的定義(1.2之前):如果reference類型的數據中存儲的數值代表的是另外一塊內存的起始地址。

但是在1.2之後,JAVA對引用進行了擴充,又分出以下四種(這裏不知道大家有沒有和我一開始一樣的困惑,這個引用類型不是說程序執行之後動態產生的引用狀態,而是在我們開發的時候,自己手動設置的引用類型)。

1 強引用:類似Object o = new Object()這類的引用,只要引用還在,即使出現OutOfMemoryError也不會被回收。

2 軟引用:使用WeakReference類來創建,代碼如下,當a=null的時候,垃圾收集器將會把a列入回收範圍,在內存不足時進行回收。屬於有用但非必需的對象。

A a = new A();

SoftReference b = new SoftReference (a);

3 弱引用:使用WeakReference類來創建,代碼如下,當a=null的時候,垃圾收集器將會把a列入回收範圍,垃圾收集的時候會被立刻回收。屬於非必需的對象。

4 虛引用:使用PhantomReference類來創建,不會對垃圾回收構成任何影響,用處是可以在被回收時接到一個系統通知。。

對象死亡會經歷兩次標記的過程,流程如下圖所示。


回收方法區

1 在新生代中,回收率效率,很高可以達到70%到95%的空間

2 在永久代中,主要回收廢棄常量和無用的類


“無用的類”的判定條件:

1. 該類所有的實例已經被回收

2. 加載該類的ClassLoder已經被回收

3. 該類對應的java.lang.Class對象沒有任何對方被引用


發佈了40 篇原創文章 · 獲贊 5 · 訪問量 9121
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章