點擊藍色「程序員的時光 」關注我 ,標註「星標」,及時閱讀最新技術文章!
小夥伴兒們,你們好!上一次咱們瞭解了JVM基礎知識——全面解析JVM,超詳細!
今天來學習JVM垃圾回收相關內容,做爲面試必問的知識點,來深刻了解一波!
1,判斷對象是否死亡

1.1,引用計數算法
public class ReferenceCountingGc {
public Object instance = null;
public static final int _1MB = 1024*1024;
public static void main(String[] args) {
ReferenceCountingGc objA = new ReferenceCountingGc();
ReferenceCountingGc objB = new ReferenceCountingGc();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
}
}
1.2,可達性分析算法

-
虛擬機棧(棧幀中的本地變量表)中引用的對象 -
方法區中類靜態屬性引用的對象 -
方法區中常量引用的對象 -
本地方法棧(Native 方法)中引用的對象
2,再談引用
reference
類型的數據存儲的數值表明的是另外一塊內存的起始地址,就稱這塊內存表明一個引用。JDK1.2 之後,Java 對引用的概念進行了擴充,將引用分爲強引用、軟引用、弱引用、虛引用四種(引用強度逐漸減弱)。
2.1,強引用
OutOfMemoryError
錯誤,使程序異常終止,也不會靠隨意回收具備強引用的對象來解決內存不足問題。
2.2,軟引用
ReferenceQueue
)聯合使用,若是軟引用所引用的對象被垃圾回收,JAVA 虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。
2.3,弱引用
ReferenceQueue
)聯合使用,若是弱引用所引用的對象被垃圾回收,Java 虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。
2.4,虛引用
OutOfMemory
)等問題的產生。
3,廢棄常量以及無用類
3.1,如何判斷一個常量是廢棄常量?
abc
" ,若是當前沒有任何
String
對象引用該字符串常量的話,就說明常量"
abc
"就是廢棄常量,若是這時發生內存回收的話並且有必要的話,"
abc
"就會被系統清理出常量池。
3.2,如何判斷一個類是無用的類?
-
該類全部的實例都已經被回收,也就是 Java 堆中不存在該類的任何實例。 -
加載該類的 ClassLoader
已經被回收。 -
該類對應的 java.lang.Class
對象沒有在任何地方被引用,沒法在任何地方經過反射訪問該類的方法。
4,垃圾收集算法
4.1,標記--清除算法
-
效率問題:標記和清除兩個過程的效率都不高; -
空間問題:標記清除以後會產生大量不連續的內存碎片,空間碎片太多可能會致使之後在程序運行過程當中須要分配較大對象時,沒法找到足夠的連續內存而不得不提早觸發另外一次垃圾收集動做。

4.2,複製算法

4.3,標記--整理算法

4.4,分代收集算法
5,垃圾收集器

5.1,Serial
收集器
Serial
收集器是最基本、歷史最悠久的垃圾收集器了。從名字上看是串行的意思,這個收集器是一個單線程的新生代收集器。它的 「單線程」 的意義不只僅意味着它只會使用一條垃圾收集線程去完成垃圾收集工做,更重要的是它在進行垃圾收集工做的時候必須暫停其餘全部的工做線程( "Stop The World" ),直到它收集結束。

5.2,ParNew
收集器

-
並行(Parallel) :指多條垃圾收集線程並行工做,但此時用戶線程仍然處於等待狀態。 -
併發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不必定是並行,可能會交替執行),用戶程序在繼續運行,而垃圾收集器運行在另外一個 CPU 上。
5.3,Parallel Scavenge
收集器

java -XX:+PrintCommandLineFlags -version
命令查看
-XX:InitialHeapSize=197918400 -XX:MaxHeapSize=3166694400 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Parallel Scavenge + Parallel Old
,若是指定了
-XX:+UseParallelGC
參數,則默認指定了
-XX:+UseParallelOld GC
,可使用
-XX:-UseParallelOldGC
來禁用該功能。
5.4,Serial Old
收集器
5.5,Parallel Old
收集器
5.6,CMS
收集器
-
初始標記: 暫停全部的其餘線程,並記錄下直接與 root 相連的對象,速度很快 ; -
併發標記: 同時開啓 GC 和用戶線程,用一個閉包結構去記錄可達對象。但在這個階段結束,這個閉包結構並不能保證包含當前全部的可達對象。由於用戶線程可能會不斷的更新引用域,因此 GC 線程沒法保證可達性分析的實時性。因此這個算法裏會跟蹤記錄這些發生引用更新的地方。 -
從新標記: 從新標記階段就是爲了修正併發標記期間由於用戶程序繼續運行而致使標記產生變更的那一部分對象的標記記錄,這個階段的停頓時間通常會比初始標記階段的時間稍長,遠遠比並發標記階段時間短 -
併發清除: 開啓用戶線程,同時 GC 線程開始對未標記的區域作清掃。

-
對 CPU 資源敏感; -
沒法處理浮動垃圾; -
它使用的回收算法-「標記-清除」算法會致使收集結束時會有大量空間碎片產生。
5.7,G1
收集器
-
並行與併發:G1 能充分利用 CPU、多核環境下的硬件優點,使用多個 CPU(CPU 或者 CPU 核心)來縮短 Stop-The-World 停頓時間。部分其餘收集器本來須要停頓 Java 線程執行的 GC 動做,G1 收集器仍然能夠經過併發的方式讓 java 程序繼續執行。 -
分代收集:雖然 G1 能夠不須要其餘收集器配合就能獨立管理整個 GC 堆,可是仍是保留了分代的概念。 -
空間整合:與 CMS 的「標記--清理」算法不一樣,G1 從總體來看是基於「標記整理」算法實現的收集器;從局部上來看是基於「複製」算法實現的。 -
可預測的停頓:這是 G1 相對於 CMS 的另外一個大優點,下降停頓時間是 G1 和 CMS 共同的關注點,但 G1 除了追求低停頓外,還能創建可預測的停頓時間模型,能讓使用者明確指定在一個長度爲 M 毫秒的時間片斷內。

《深刻理解Java虛擬機(第2版).周志明》
https://xiaozhuanlan.com/topic/1847690325#section1java
本文分享自微信公衆號 - 程序員的時光(gh_9211ec727426)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。java