Chakra GC内存管理(未完)

这一部分是我在网上找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;//用户申请的大小
      }
    
  • 0x2400以上 last large alloc

    //to do

Recycler管理

class	Recycler
0x26c	m_HeaoBlock32Map
0x42bc	m_HeapInfo

//to do

HeapBlock32Map

//to do

posted @ 2017-08-08 18:35  Ox9A82  阅读(623)  评论(0编辑  收藏  举报