java講義之垃圾回收機制

垃圾回收機制:概述

1.垃圾回收機制作用:用來回收我們動態創建的,不用的對象,

2.垃圾回收算法:主要是根據類的生命週期來的。

          類的生命週期的順序:加載-驗證-準備-解析-初始化-使用-卸載

垃圾回收機制就是描述的最後一個卸載過程,也就是把垃圾如何從內存中回收的問題。

帶着下面四個問題來學習:

首先,回顧一下jvm中的內存結構然後,確定那些對象是垃圾?

其次,有哪些算法回收這些垃圾?

接下來,jvm提供了哪些垃圾回收器

最後,對垃圾回收機制進行一個總結

一、jvm的內存結構

                                                                                java 的內存結構

 由上圖而知:  運行時區域分爲三部分:

1.PC寄存器、java虛擬機棧、本地方法棧3個區域是所有線程獨有的一塊區域,隨線程而生,隨線程而滅。自動回收無需考慮

2.堆和方法區 重點關注對象,因爲這兩個區域是 存放着被調用的類,或方法中的對象,只有在程序處於運行期間時才能知道會創建哪些對象,這部分內存的分配和回收是動態的

第一個問題的答案: 堆和方法區的對象是我們重點要監控,且需要回收對象的存在的區域.

二. 哪些對象是垃圾呢?

     爲了確定哪些對象是垃圾,  jvm爲我們提供了一些算法去判定。常見的判斷是否存活有兩種方法:引用計數法和可達性分析。

1.引用計數法

    用一次,記一次. 爲0時,就是死亡對象,  存在問題,循環引用,導致永遠不會回收,..

    例如:兩個類相互是對方的成員變量,toString的時候,相互調用。造成循環引用。因此,java並沒有採用此方案來判斷

2.可達性分析

     已樹形結構爲準,沒有和根節點連接的,都被稱爲不可達對象,等待被回收,

3.Java 裏有哪些對象可以作爲GC Roots呢?主要有以下四種:

虛擬機棧(幀棧中的本地變量表)中引用的對象。

方法區中靜態屬性引用的對象。

方法區中常量引用的對象。

本地方法棧中 JNI 引用的對象。

三.有哪些算法回收這些垃圾呢?

1、標記-清理 , 特點:簡單,容易產生內存碎片

 用可達性遍歷內存,把“存活”對象和“垃圾”對象標記。第二步(清理),再遍歷一遍,把“垃圾”對象所佔的空間直接 清空 即可。

2.  標記-整理 特點: 適合存活對象多,垃圾少的情況,需要整理的過程

     第一步(標記):利用可達性遍歷內存,把“存活”對象和“垃圾”對象進行標記。

      第二步(整理):把所有存活對象堆到同一個地方,這樣就沒有內存碎片了。

3.複製 -轉移-清理 特點:簡單,不會產生隨便,內存利用率低,只用了一半

將內存按照容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊用完了,就將還活着的對象複製到另一塊上,然後再把使用過的內存空間一次性清理掉

四、堆和方法區的垃圾回收

         上面提到了三種方法來回收內存 , 第四種是 分代回收算法。

        1.方法區的垃圾回收

        方法區又叫做永久代。永久代的垃圾回收主要有兩部分:廢棄常量和無用的類。

                廢棄常量=沒有任何一個地方對這個常量進行引用就表示是廢棄常量。

                無用的類=需要滿足下面三個條件

                          Java堆中不存在該類的任何實例,也就是該類的所有實例都被回收

                          加載該類的ClassLoader已經被回收

                           該類對應的Class對象在任何地方沒有引用了,也不能通過反射訪問該類的方法。

注意:《java虛擬機規範》裏面曾經說到過,不要求虛擬機對方法區進行垃圾回收。而且方法區進行垃圾回收性價比比較低。

       2、Java 堆的垃圾回收:分代回收算法

       

Java 堆空間分成了三部分,這三部分用來存儲三類數據:

           剛剛創建的對象。存活了一段時間的對象。永久存在的對象。

常規的 Java 堆至少包括了 新生代 和 老年代 兩塊內存區域,而且這兩塊區域有很明顯的特徵:

           新生代:存活對象少、垃圾多老年代:存活對象多、垃圾少

(1)新生代-複製 回收機制  特點:   存活對象少、垃圾多  

         對於新生代區域,由於每次 GC 都會有大量新對象死去,只有少量存活。因此採用 複製 回收算法,GC 時把少量的存活對象複製過去即可。但是從上面我們可以看到,新生代也劃分了三個部分比例:Eden:S1:S2=8:1:1。

其中 Eden 意爲伊甸園,形容有很多新生對象在裏面創建;S1和S2中的S表示Survivor,爲倖存者,即經歷 GC 後仍然存活下來的對象。

          工作原理: Eden提供內存,快要滿時,觸發機制,複製存活到A區,清空Eden ,清完重新對外提供內存.再次快滿,觸發機制,複製

Eden和A區的存活對象到B區, 清空Eden和A區,當某個A或B 被填滿,把多餘對象放到Old 區;當OLd也滿的時候,重新進行垃圾回收

         快速理解(拿一個篩子(Eden)和兩個碗(Survivor),過濾海里的沙(死去的對象),直到過濾出來金子(OLd))

(2)老年代-標記整理 回收機制  特點是:存活對象多、垃圾少。

        僅僅通過少量地移動對象就能清理垃圾,而且不存在內存碎片化。也就是標記整理的回收機制。

五.垃圾回收器 :有算法了.缺少一個執行工具, 這個工具就是(垃圾回收器)

首先得了解一下垃圾回收器的幾個名詞。

1. 吞吐量:

          CPU 用於運行用戶代碼的時間與 CPU 總消耗時間的比值。比如說虛擬機總運行了 100 分鐘,用戶代碼時間 99 分鐘,垃圾回收 時間 1 分鐘,那麼吞吐量就是 99%。

2. 停頓時間    指垃圾回收器正在運行時,應用程序 的 暫停時間。

3. GC的名詞  新生代GC:Minor GC   老年代GC:Major GC

4.併發與並行

(1)串行(Parallel) 垃圾回收線程 進行垃圾回收工作,但此時 用戶線程 仍然處於 等待狀態。

(2)併發(Concurrent)這裏的併發指 用戶線程 與 垃圾回收線程 交替執行。

(3)並行(Parallel)這裏的並行指 用戶線程 和多條 垃圾回收線程 分別在不同 CPU 上同時工作。

在 JVM 中,具體實現有 Serial、ParNew、Parallel Scavenge、CMS、Serial Old(MSC)、Parallel Old、G1 等。在上圖中,你可以看到 不同垃圾回收器 適合於 不同的內存區域,如果兩個垃圾回收器之間 存在連線,那麼表示兩者可以 配合使用。

下面對這其中垃圾回收器有一個瞭解。

第一種:Serial(單線程)

Serial 回收器是最基本的 新生代垃圾回收器,是單線程的垃圾回收器。採用的是 複製算法。垃圾清理時,Serial回收器不存在線程間的切換,因此,在單 CPU` 的環境下,垃圾清除效率比較高。

第二種:Serial Old(單線程)

Serial Old回收器是 Serial回收器的老生代版本,單線程回收器,使用 標記-整理算法。在 JDK1.5 及其以前,它常與Parallel Scavenge回收器配合使用,達到較好的吞吐量,另外它也是 CMS 回收器在Concurrent Mode Failure時的後備方案。

第三種:ParNew(多線程)

ParNew回收器是在Serial回收器的基礎上演化而來的,屬於Serial回收器的多線程版本,採用複製算法。運行在新生代區域。在實現上,兩者共用很多代碼。在不同運行環境下,根據CPU核數,開啓不同的線程數,從而達到最優的垃圾回收效果。

第四種:Parallel Scavenge(多線程)

Parallel Scavenge回收器也是運行在新生代區域,屬於多線程的回收器,採用複製算法。與ParNew不同的是,ParNew回收器是通過控制垃圾回收的線程數來進行參數調整,而Parallel Scavenge回收器更關心的是程序運行的吞吐量。即一段時間內用戶代碼運行時間佔總運行時間的百分比。

第五種:Parallel Old(多線程)

Parallel Old回收器是Parallel Scavenge回收器的老生代版本,屬於多線程回收器,採用標記-整理算法。Parallel Old回收器和Parallel Scavenge回收器同樣考慮了吞吐量優先這一指標,非常適合那些注重吞吐量和CPU資源敏感的場合。

第六種:CMS(多線程回收)

CMS回收器是在最短回收停頓時間爲前提的回收器,屬於多線程回收器,採用標記-清除算法。

第七種:G1回收器

G1是 JDK 1.7中正式投入使用的用於取代CMS的壓縮回收器。它雖然沒有在物理上隔斷新生代與老生代,但是仍然屬於分代垃圾回收器。G1仍然會區分年輕代與老年代,年輕代依然分有Eden區與Survivor區。

G1首先將堆分爲大小相等的 Region,避免全區域的垃圾回收。G1的分區示例如下圖所示:

這種使用區域劃分內存空間以及有優先級的區域回收方式,保證G1回收器在有限的時間內可以獲得儘可能高的回收效率。

下面對這幾種垃圾回收機制進行一個總結:

六:學習完畢,歡迎批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章