這一部分是我在網上找Chakra資料的時候偶然發現的zenhumany師傅在Hitcon2015上的議題《Microsoft Edge MemGC Internals》,感覺正好可以瞭解一下chakra的底層機制。但是隻有一個PPT理解起來比較費力,這裡的內容一方面是靠理解ppt,一方面是靠看程式碼和除錯,可能有不正確的地方。
GC的管理模式
Chakra GC use Concurrent Mark-Sweep (CMS) Managing Memory.
Edge use the same data structures to mange DOM and DOM’S supporting objects, called MemGC.
GC針對堆的管理
GC根據分配的size大小分為三類的block。
總體的管理器為HeapInfo
class HeapInfo
m_HeapBucketGroup[0x40] 陣列
m_LargeHeapBucket[0x20] 陣列
m_lastLargeHeapBucket
0x400byte以下為small block (目前版本可能改成了0x300)
資料結構
pHeapInfo
->m_HeapBucketGroup[index]
->m_HeapBucketT<SmallNormalHeapBlock>(子結構)
->pSmallHeapBlockAllocatorT(子結構)
->pSmallHeapBlock
class HeapBucketT<SmallNormalHeapBlock>
size
m_SmallHeapBlockAllocator
pPartialReuseHeapBlockList
pEmptyHeapBlockList
pFullMarkedHeapBlockList
pPendingNewHeapBlockList
HeapBucketT是模版類用於對應不同的block型別,目前還不清楚各個list的作用,一些似乎是用於垃圾回收的
其中SmallHeapBlockAllocator是small block分配的重要結構,startaddress域儲存有下一次分配的起始地址,
SmallHeapBlockAllocator<SmallNormalHeapBlock>
0x00 endadderss
0x04 startaddress
0x08 pSmallNormalHeapblock
其中SmallHeapBlockAllocator是直接的記憶體控制結構。
pSmallNormalHeapblock是直接對應buffer的底層結構
分配的過程如下:
pHeapInfo->
m_HeapBucketGroup[ index].m_HeapBucketT<SmallNormalHeapBlock>->
pSmallHeapBlockAllocatorT(子結構)->
pSmallHeapBlock
allocAddress = pHeapBucketT->startAddress;//取pSmallHeapBlockAllocatorT中地址
...//省略了一些校驗
pSmallHeapBlockAllocator->startAddress = pHeapBucketT->startAddress + align_size;
return allocAddress;
分配是透過直接讀取操作pSmallHeapBlockAllocatorT中的address實現的
但是如果startaddress不存在的話會進入另一個分配機制稱為慢分配
if( pSmallHeapBlockAllocator->startAddress ==0 || pSmallHeapBlockAllocator->endAddress!=0 )
{
allocAddress = pHeapBucketT->SnailAlloc(pRecycler, pSmallHeapBlockAllocator, align_size, 8, 1);
if( allocAddress == 0)
return 0;
else
*allocAddress = 0;
return allocAddress
}
0x400-0x2400為large block (目前版本的size範圍有不同)
資料結構
pHeapInfo
->m_LargeHeapBucket[index]
->pNewLargeHeapBlockList
分配過程
pHeapInfo->m_LargeHeapBucket[ largebucketIndex]->pLargeHeapBlockList->Alloc( align_size, 8)
allocAddress = pLargeHeapBlock ->Alloc( align_size, 8)
return allocAddress;
Recycler::LargeAlloc
allocAddress = Recycler::LargeAlloc( pHeapInfo, size, 8 )//使用到了Recycler
*allocAddress = 0;
return allocAddress;
其中LargeHeapBlock是底層的記憶體管理結構
LargeHeapBlock管理著LargeObjectHeader和對應的buffer
LargeObjectHeader
Buffer
LargeObjectHeader
Buffer
LargeObjectHeader存在分配的序號進行排列
struct LargeObjectHeader
{
uint objectIndex;//分配的序號
UINT_PAD_64BIT(unused1);
size_t objectSize;//使用者申請的大小
}
Recycler管理
class Recycler
0x26c m_HeaoBlock32Map
0x42bc m_HeapInfo
//to do
HeapBlock32Map
//to do