首先了解下標(biāo)記清除算法的概念:GC 標(biāo)記 - 清除算法由標(biāo)記階段和清除階段構(gòu)成褐望。標(biāo)記階段是
把所有活動對象都做上標(biāo)記的階段。清除階段是把那些沒有標(biāo)記的對象实蔽,也就是非活動對象
回收的階段。下面我們帶著問題去看 既然是標(biāo)記清除算法那么是如何標(biāo)記的呢
1.是如何標(biāo)記的其中涉及的問題
(1)標(biāo)記過程中如何確定引用的對象是都為垃圾對象坛吁?
可達(dá)性分析
(2)在過程中使用的是什么數(shù)據(jù)結(jié)構(gòu)铐尚?
一GCRoot為起點(diǎn)以引用為指向一被引用為執(zhí)行的有向圖
(3)標(biāo)記的是什么地方
在對象的頭部有一個(gè)判斷是否被標(biāo)記的變量
(4)標(biāo)記過程搜索中是如何遍歷的
使用深度優(yōu)先遍歷 宣增,他比廣度優(yōu)先遍歷需要存儲對象更少
深度搜索圖
廣度搜索圖
標(biāo)記說完了那說一下如何清除的吧
在回收過程中會有一個(gè)空閑的鏈表來保存回收分塊爹脾,在清除的時(shí)候會遍歷整個(gè)堆 找到頭部沒有被標(biāo)記的分塊,是它指向空閑的鏈表解阅。
為什么會有空閑鏈表 空閑鏈表的作用是什么泌霍?
1.在垃圾回收記錄垃圾回收的分塊大小
2.在需要內(nèi)存是對內(nèi)存進(jìn)行重新分配
空閑鏈表的重新分配策略有什么?
First -fit:最初發(fā)現(xiàn)大于等于size 的分塊時(shí)就會立即返回該分塊
Best -fit:遍歷空閑鏈表蟹地,返回大于等于 size 的最小分塊
Worst -fit:即找出空閑鏈表中最大的分塊肋拔,將其分割成 mutator 申請的大小和分割后剩余的大小凉蜂,目的是將分割后剩余的分塊最大化。但因?yàn)?Worst -fit 很容易生成大量小的分塊窿吩,所以不推薦大家使用此方法
說了那么多標(biāo)記清除算法他有什么優(yōu)缺點(diǎn)呢纫雁?
優(yōu)點(diǎn)
1绿店、實(shí)現(xiàn)簡單
2、不移動對象,與保守式GC算法兼容却邓。在保守式GC算法中對象是不能移動的院水。
算法的缺點(diǎn):
1、內(nèi)存碎片化撬腾。因?yàn)閷ο蟛灰苿踊帜眨詫?dǎo)致塊是不連續(xù)的,容易出現(xiàn)空閑內(nèi)存很多饰潜,但分配大對象時(shí)找不到合適的塊和簸。
2锁保、分配速度慢半沽。即使是First-fit,但其操作仍是一個(gè)O(n)的操作浩村,最壞情況是每次都要遍歷到最后占哟。同時(shí)因?yàn)樗槠髮ο蟮姆峙湫蕰?br>
有什么可以優(yōu)化的地方嗎怎燥?
(1)優(yōu)化分配速度:使用多條空閑鏈表
利用不同分塊大小的分塊分別放在不同的大小里面蜜暑,為了防止分塊過多設(shè)置一個(gè)閾值,超過某個(gè)閾值的分塊全部放到這個(gè)分塊里面隐绵,這樣在分配的時(shí)候就不用遍歷整個(gè)空閑鏈表去取了,這直接到所需要的的分塊大小對應(yīng)的分塊鏈表中去取就行了棺禾,這個(gè)可以優(yōu)化分配速度.
(2)內(nèi)存碎片化優(yōu)化:使用BiBOP悍手,就是將大小相近的對象整理成固定大小的塊進(jìn)行管理的做法坦康,我們使用這個(gè)方法把堆分割成固定大小的塊,讓每個(gè)塊只能配置同樣大小的對象古胆,
(3)使用位圖標(biāo)記
我們單獨(dú)做一個(gè)位圖表格來存儲逸绎,在當(dāng)前堆里面當(dāng)前區(qū)塊是否被標(biāo)記的信息夭谤,是清除是只需要遍歷當(dāng)前位圖表格就行了