.NET?Core?GC壓縮(compact_phase)底層原理解析
簡(jiǎn)介
終于來(lái)到了GC的最后一個(gè)步驟,在此之間,大量預(yù)備工作已經(jīng)完成。萬(wàn)事俱備,只欠東風(fēng)
清除
如果GC決定不壓縮,它將僅執(zhí)行清除操作。清除操作非常簡(jiǎn)單,把所有不可到達(dá)對(duì)象(gap),轉(zhuǎn)換成Free。也就是轉(zhuǎn)換成空閑內(nèi)存空間。由于所有的繁重計(jì)算任務(wù)在plan_phase階段均已完成,所以步驟比較簡(jiǎn)單
基于gap的size創(chuàng)建空閑列表free > 2 * min_obj_size 的Free塊會(huì)被放入空閑列表,小于此大小的不再被利用,但會(huì)納入內(nèi)存碎片統(tǒng)計(jì)
恢復(fù)“被銷(xiāo)毀”的前置plug和plug這是pinned 對(duì)象的特殊情況,pinned的plug前面可能還是一個(gè)plug,所以沒(méi)有g(shù)ap來(lái)存放, 因此會(huì)根據(jù)實(shí)際情況“釘住”它的前面或者后面的Plug.來(lái)暫存gap_reloc_pair信息。 所以用完后還要“還回去”
更新終結(jié)隊(duì)列,并提升或降低plug的代
更新段空間

眼見(jiàn)為實(shí)

壓縮
如果GC決定壓縮,就比較復(fù)雜了??傮w分為兩步
復(fù)制對(duì)象并移動(dòng)到新位置(重定位階段)將新對(duì)象的地址在root上更新GC重定位階段
此步驟更新所有對(duì)稍后要移動(dòng)對(duì)象的引用,為了更新這些地址,要掃描他們的root,并逐一更新
??臻g的root跨代記憶集的root托管堆中的root前置plug與后置Plug的root終結(jié)器隊(duì)列的root句柄表的root
比如某個(gè)對(duì)象的內(nèi)存地址為0x1000,壓縮后它的新地址為0x500。那就就要對(duì)該對(duì)象的所有root更新內(nèi)存地址。
眼見(jiàn)為實(shí)
internal class Program
{
static void Main(string[] args)
{
Append();
AppendStatic();
Compact();
}
public static Person person;
public static List<byte[]> list = new List<byte[]>();
static void Append()
{
//填 10M 數(shù)組到 臨時(shí)段上
for (int i = 0; i < 1024 * 10; i++)
{
list.Add(new byte[1000]);
}
Console.WriteLine("1. 10M 數(shù)據(jù)已分配完畢,請(qǐng)查看臨時(shí)段大小,準(zhǔn)備分配 Person 對(duì)象!");
Debugger.Break();
}
static void AppendStatic()
{
person = new Person();
list = null;
Console.WriteLine("2. Person 已分配,list已去根,請(qǐng)?jiān)俅斡^察托管堆!準(zhǔn)備觸發(fā) GC,請(qǐng)下 compact_phase 斷點(diǎn)!");
Debugger.Break();
}
static void Compact()
{
GC.Collect(2, GCCollectionMode.Forced, true, true);
Console.WriteLine("3. GC 已觸發(fā),請(qǐng)觀察 Person 是否已變!");
Debugger.Break();
}
}
public class Person { }在bp coreclr!WKS::gc_heap::compact_phase 下斷點(diǎn),觀察對(duì)象的新老地址變化GC前:

GC后:內(nèi)存地址發(fā)生變化

眼見(jiàn)為實(shí)

壓縮對(duì)象
在上面更新root的操作完成后,GC要移動(dòng)所有對(duì)象。由以下幾個(gè)步驟組成
復(fù)制對(duì)象恢復(fù)“被銷(xiāo)毀”的前置plug和plug重新劃分代邊界釋放內(nèi)存段創(chuàng)建空閑列表眼見(jiàn)為實(shí)
GC前:

GC后:對(duì)象被移動(dòng),原有地址被壓縮釋放

眼見(jiàn)為實(shí):復(fù)制連續(xù)的內(nèi)存區(qū)域
以滑動(dòng)的方式來(lái)copy內(nèi)存,避免出現(xiàn)覆蓋問(wèn)題

到此這篇關(guān)于.NET Core GC壓縮(compact_phase)底層原理淺談的文章就介紹到這了,更多相關(guān).NET Core GC壓縮(compact_phase)底層原理淺談內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何在網(wǎng)站級(jí)別動(dòng)態(tài)更改主題
如何在網(wǎng)站級(jí)別動(dòng)態(tài)更改主題...2007-04-04
為T(mén)extBox裝飾水印與(blur和focus)事件應(yīng)用
為了界面的美觀,有些時(shí)候可能需要為文本框(TextBox)裝飾個(gè)水?。凰袃煞N狀態(tài),一是blur和focus。因此,我們可以在Javascript寫(xiě)兩個(gè)事件,感興趣的朋友可以了解下2013-01-01
將文件上傳、下載(以二進(jìn)制流保存到數(shù)據(jù)庫(kù))實(shí)現(xiàn)代碼
將文件以二進(jìn)制流的格式寫(xiě)入數(shù)據(jù)庫(kù):首先獲得文件路徑,然后將文件以二進(jìn)制讀出保存在一個(gè)二進(jìn)制數(shù)組中具體請(qǐng)祥看本文,希望對(duì)你有所幫助2013-05-05
C#中efcore-ShardingCore呈現(xiàn)“完美”分表
本文簡(jiǎn)單的介紹了efcore的分表,著重介紹了efcore下最完美的分表組件ShardingCore,可以幫助大家更好的學(xué)習(xí),感興趣的小伙伴可以參考一下2021-08-08
.net連接oracle的3種實(shí)現(xiàn)方法
這篇文章介紹了.net連接oracle的3種實(shí)現(xiàn)方法,有需要的朋友可以才可以一下2013-07-07
asp.net 數(shù)據(jù)綁定 使用eval 時(shí)候報(bào) 字符文本中的字符太多 問(wèn)題的解決方法
asp.net 數(shù)據(jù)綁定 使用eval 時(shí)候報(bào) 字符文本中的字符太多 問(wèn)題解決,需要的朋友可以參考下。2010-09-09
ASP.NET通過(guò)Remoting service上傳文件
ASP.NET通過(guò)Remoting service上傳文件...2006-09-09
asp.net4.0框架下驗(yàn)證機(jī)制失效的原因及處理辦法
asp.net4.0框架下驗(yàn)證機(jī)制失效的原因及處理辦法,需要的朋友可以參考一下2013-06-06

