一、找出垃圾的算法?
1.引用計數算法,
1.原理:
給每個對象設置一個計數器,有地方引用這個對象的時候,計數器+1,引用失效的時候,計數器-1,計數器爲0的時候,就銷燬對象。
優點|
- 1.實現簡單,效率高
缺點
- 1.不能解決循環引用的問題(A引用B,B引用A,但是A,B又不被其他對象所引用)
所以已經棄用了!!
- 2.計數器的增加和減少都是浪費資源.
方法已經棄用,瞭解即可.
2.根搜索法
1.以GCRoots 作爲起點,開始搜索,通過搜索的路徑形成引用鏈條,
當一個對象沒有被 GCRoots 的引用鏈條引用的時候,說明這個對象是不可用的。可以清楚
2.GC對象包括:
- (1)虛擬機棧的引用對象
- (2)方法區類靜態屬性引用對象
- (3)方法區的常量引用對象
- (4)本地方法棧JNI(Java Native Interface )的引用對象
二、垃圾回收過程(分代收集算法)
1.(基本)垃圾回收的過程點擊查看更多
上面的輸出太亂我們來分析下
1.如果Eden區滿了,出發一次輕度垃圾回收 minor GC ,過程如下.
- (1)比如Eden的10個空間滿了,將還需要使用的對象 1
複製
到 倖存區 0(倖存區0和1是動態替換的一般都有一個空白的) - (2)。將消亡的 9 個對象清理掉
2.到下一次Eden區滿了,就再 Minor GC ,
- 1.將Eden存活的(假設1個)對象複製到
倖存區1中
, - 2.清理Eden區消亡的對象(假設9個)
- 3.將 倖存0區 的對象(假設3個),存活的
複製
到倖存1區 - 4.將 倖存0區 的對象(假設3個-1個),能晉升的晉升到 老年區**(能晉升的條件??)**
- 5.銷燬倖存者0區 還剩下的 1個對象.
註釋:
(此時倖存者0區空白,下一次一般倖存者1區空白,所以一般都有一個倖存者空白的)
3.15歲對象進入老年區.
(1)JVM給每個對象定義了一個年齡計數器
(2)如果對象在 Eden區出生,經過一次 輕度垃圾回收 Minor GC 後依舊存活,並且能被 倖存區 Survivor 容納,對象的年齡就 爲 1 ,沒經過一次垃圾回收年齡+1,默認15歲,進入老年區
- (可以JVM調優: -XX:MaxTenuringThreshold15)
3.(特殊01)大對象直接進入老年區.
1.什麼是 – 大對 象?
(1)大量連續的內存空間的Java對象
(2)比如很長的字符串或者數組.
(3)JVM調參:-XX:PretenureSizeThreshold參數,大於這個參數的值就是大對象.
2.目的:避免在Enden 和 倖存區Survivor 之間發生多次大量內存的複製.
4.(特殊02)動態對象年齡判定
(1)對象並不是只有15歲才進入老年,
(2)當倖存區的某個年齡**(4歲)的所有對象空間大小的總合大於 倖存者空間的一半**,大於或者等於 (4歲)的對象直接進入老年區.
5.(特殊03)分擔擔保機制:
(1)當發生Minor GC 的時候(需要重Eden轉移的對象有20個),發現Survivor倖存者空間不足(只有10個),部分對象無法複製到Survivor倖存者空間,虛擬機可通過分擔擔保機制將這些對象提前轉移到老年區
6 (特殊04)空間分配擔保策略,
(1)GC 之前,虛擬機先檢查老年區的最大可用連續空間是否大於新生區的所有的對象的總空間,
(2)如果空間夠大,GC絕對安全。(通過分擔擔保機制就能保證安全,)
(3)如果不夠大,GC存在風險的可能,
- 1.JVM 會查看 HandlePromotionFailure 設置是否可以冒險
- 2.可以冒險,檢查老年區最大可用連續空間是否大於晉升到老年對象的平均大小,
- 3.如果可以冒險,並且 大於 老年對象平均大小---------Minor GC輕度清理.
- 4.如果不能冒險,或者小於老年對象平均大小 -----------Full GC重度清理.
三、垃圾回收算法
1.複製算法
1.定義:
按照內存的容量的大小分爲大小相等的2塊(HotSpot Eden:倖存Survivor = 8:1),每次只使用其中的一塊,當這一塊內存用完了,就執行一次輕度GC 然後把活着的 給另一塊,使用過的內存一次清理掉.參考新生代的垃圾回收 (比如倖存 0 1 區)
優點 | 效率高沒有內存碎片 |
---|---|
缺點 | 1.浪費一般的內存空間 |
侷限 | 存活率高的(10個對象9個存活)效率變低,且浪費內存. |
參考 | 新生代的垃圾回收 |
2. 標記清除算法.
1.定義:
清除所有被根搜索法
,標記的無用對象。
3.優點缺點:
優點 | 只用一塊內存節約內存. |
---|---|
缺點1 | 內存碎片,內存不連續. |
缺點2 | 標記和清除需要浪費時間,效率不高. |
參考 | 老年區 |
4.圖解
3. 標記整理算法
1.定義:
標記對象,先向端移動再清理.
2.步驟:
- 1.標記
- 2.移動
- 3.清除
3.優點缺點:
優點 | 無內存碎片 |
---|---|
缺點1 | 比標記清除算法還慢,效率極低. |
參考 | 老年區 |
4.圖解
4. 三大GC算法的比較.
速度 | 複製 —> 清除 —> 整理 |
---|---|
無內存碎片 | 複製 = 整理 —> 清除 |
內存利用率 | 整理 = 清除 —> 複製 |
5. 那個算法最好?(分代收集算法)
答案是,都不好,沒有最好的只有最合適的,什麼最合適?分代收集算法分帶收集算法就是JVM GC 的常用算法。
1.定義:
把堆內存分爲新生區和老年區,不同的區域使用不同的算法(1,2,3)
2.步驟(參考二、點)
*1.對象優先在新生代的Eden區出生,然後99%(一般大多數都是局部對象)在新生區的銷燬,新生區複製算法
- 2。達到條件的(1. 15歲,或者 2.大對象 或者 3.很多年齡一致的對象)進入老年區 標記清除算法 和 標記整理算法。