这一部分是我在网上找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和对应的bufferLargeObjectHeader Buffer LargeObjectHeader Buffer
LargeObjectHeader存在分配的序号进行排列
struct LargeObjectHeader { uint objectIndex;//分配的序号 UINT_PAD_64BIT(unused1); size_t objectSize;//用户申请的大小 }
-
0x2400以上 last large alloc
//to do
Recycler管理
class Recycler
0x26c m_HeaoBlock32Map
0x42bc m_HeapInfo
//to do
HeapBlock32Map
//to do