JVM垃圾收集

一.jvm判斷對象是否已死的方法

1.引用計數法,缺陷-很難解決對象之間相互循環引用的問題。java

2.根搜索算法,經過一系列的名爲"GC Roots"的對象做爲起始點,從這些節點開始向下搜索,搜索所通過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,則證實此對象是不可用的。算法

在java中,GC Roots的對象包括下面幾種:服務器

1.虛擬機棧(棧幀中的本地變量表)中引用的對象多線程

2.方法區中的類靜態屬性引用的對象jvm

3.方法區中常量引用的對象線程

4.本地方法棧中JNI(也就是Native方法)的引用的對象3d

以上兩種判斷對象是否已死的方法都和引用有關係,在jdk1.2以前,引用的定義就是若是reference類型的數據中存儲的數值表明的是另一個內存的起始地址,就稱這塊內存表明着一個引用。這顯得太對象

過狹隘,因此在jdk1.2以後呢,對於引用的概念進行了擴充:blog

1.強引用:相似"Object obj = new Object()"這類的引用,只要強引用還存在,垃圾收集器永遠不會回收掉被引用的對象。隊列

2.軟引用(SoftReference):用來描述一些還在用,但並不是必須的對象。對於軟引用關聯的對象,在系統將要發生內存溢出異常以前,將會把這些對象列進回收範圍之中並進行第二次回收(也就是說若是這

個對象在第二次引用時尚未逃離就會被回收),若是此次回收仍是沒有足夠的內存,纔會拋出內存溢出異常。

3.弱引用(WeakReference):被弱引用關聯的對象只能生存到下一次垃圾收集發生以前。

4.虛引用(PhantomReference):一個對象是否有虛引用的存在,徹底不會對其生存構成影響,也沒法經過虛引用來取得一個對象實例。爲一個對象設置虛引用的目的就是但願能在這個對象被回收時收到一個通知。

二.生存仍是死亡?

在根搜索算法中不可達的對象,也並不是是非死不可的,這時候他們暫時處於"緩刑"階段,要真正宣告一個對象死亡,至少要經歷兩次標記過程:若是對象在進行根搜索後發現沒有與GC Roots相連的引用鏈,那它將會第一次被標記而且進行一次篩選,篩選的條件的是此對象是否有必要執行finalize()方法,當對象沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機調用過,虛擬機將這兩種狀況都視爲"沒有必要執行"。

若是這個對象被斷定爲有必要執行finalize()方法,那麼這個對象會被放置在一個F-Queue隊列中,而後由一條虛擬機自動創建,低優先級的finalizer線程去執行。這裏所謂的執行是指虛擬機會觸發這個方法,但並不承諾會等待它運行結束。這樣作的緣由是,若是一個對象在finalize()方法中執行緩慢,或者發生了死循環,將極可能會致使F-Queue隊列中的其餘對象永久處於等待狀態,設置致使整個內存回收系統崩潰。

finalize()方法是對象逃脫死亡的最後一次機會,稍後GC將對F-Queue隊列中的對象進行第二次小規模的標記,若是對象在finalize()方法中成功拯救本身,那麼將在第二次標記時它將被移除'即將回收'的集合。若是對象仍是沒有逃脫,那麼離死不遠了。

三.回收方法區

在方法區中實現垃圾收集的性價比很低- 在堆中,尤爲是新生代中,常規應用進行一次垃圾收集通常能夠回收70%-95%的空間,而在永久代遠低於此。
永久代的垃圾收集主要回收兩部份內容:廢棄常量和無用的類
1.廢棄常量的回收方式和堆中的對象很是相似。就是沒有任何對象引用常量池中的某個常量,也沒有其餘地方引用這個常量,那麼就回收。若是必要的話,這個常量就會被系統「請」出常量池。
2.斷定無用的類須要知足3個條件:
該類全部的實例都已經被回收,也就是java堆中不存在該類的任何實例。
加載該類的classloader已經被回收
該類對應的java.lang.class對象沒有在任何地方被引用,沒法在任何地方經過反射訪問該類。

四.垃圾收集算法

1.標記-清除算法
缺點:效率不高,空間有浪費(產生大量不連續的空間碎片)

2.複製算法
回收新生代,由於新生代基本上都是朝生夕滅的,因此不須要按照1:1的比例來劃份內存空間,而是將內存分爲一個較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中的一塊survicor。當回收時,將Eden和survicor還存活的對象一次性拷貝到另外一塊survivor空間上,最後清理掉Eden和剛纔使用的survicor的空間。hotspot虛擬機的默認eden和survivor的大小比例是8:1。

3.標記-整理算法

4.分代收集算法 - 新生代用複製算法。老年代用標記算法

五.垃圾收集器

 

 上圖中連線的表示相互之間能夠配合使用

1.Serial收集器(新生代收集器) - 單線程的收集器,在它進行垃圾收集時,必須暫停其餘全部的工做線程,直到它收集結束。可是也有些優勢,好比簡單而高效(與其餘收集器的單線程比)
2.ParNew收集器(新生代收集器) - 其實就是Serial收集器的多線程版本,除了Serial收集器外,目前只有它能與CMS收集器配合工做。
3.Parallel Scavenge收集器(新生代收集器) - 和Parnew不一樣之處是,它的目標則是達到一個可控制的吞吐量。
4.Serial Old收集器 - Serial收集器的老年代版本
5.Parallel Old收集器 - Parallel Scavenge收集器的老年代版本
6.CMS收集器 - 一種以獲取最短回收停頓時間爲目標的收集器,重視服務器響應速度。用標記清除算法
7.G1收集器 - 基於標記整理算法實現的收集器;另外它能夠很是精確的控制停頓

下面是垃圾收集器的經常使用參數

相關文章
相關標籤/搜索