码迷,mamicode.com
首页 > 其他好文 > 详细

rosalloc

时间:2015-07-17 23:11:47      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:

1.            关键数据结构

i.            FreePageRun

描述将要用来分配的地址空间(逻辑地址空间,下同)。

ii.            Run

相同大小的slot的集合。

iii.            Slot

内存分配单位。

对于run的大小可分为34个标准(bracketSizes):标号0-31的,大小为16*(i+1)个字节,其中i为标号值,32大小为1kB332kB

不同标号的run所用page数目也不一样(numOfPages):0-3 run大小为1 page4-7的为2 page8-15的为4 page16-31的为8 page3216 page 3332 page

每个runslot的个数可以计算出。

2.            相关操作

i.            构造函数

·         Initialize

初始化bracketSizesnumOfPages等等。

·         其他

初始化free_page_runs_,第一个free page run的地址通过够在函数得到,为rosalloc space的地址,大小为capacity_

初始化其他成员变量。

ii.            Alloc

·         AllocLargeObject

如果所需分配字节数超过kLargeSizeThreshold(2048),则分配大对象。大对象内存直接通过alloc pages获得。

·         AllocFromRun

如果需要分配的长度小于192字节(级别11以下),从thread local中分配。如果超过这个值,调用AllocFromCurrentRunUnlocked函数,从共用中分配。

·         AllocFromCurrentRunUnlocked

current_runs_存放了各个编号的当前可用来分配的runAlloc函数首先从current_runs_得到即将用于分配的run,分配该run中的一个slotRunslot是通过bitmap管理,分配的时候通过bitmap计算得到空闲slot的地址,bitmap标记后返回该slot地址。如果在current run中分配失败,说明该run已满,需要调用RefillRun重新获得一个run,并将新的run记录为current run,然后重新分配slot

·         RefillRun

non_full_runs_中存放了既没有全部使用完,也不是currentrunRefill run的时候优先从non_full_runs_中获得,如果non_full_runs_没有该编号的run,就通过AllocRun获得一个全新的run

·         AllocRun

该函数主要做两件事:1、通过AllocPages获得一定数目的pagepage数目根据编号确定);

2、对分出来的run进行初始化。如果alloc pages失败,返回Null

·         AllocPages

free_page_runs_存放了用于分配page的空间。Alloc page函数从free_page_runs_头开始查找,寻找大于所需求大小的free page run。查找结果可能两种:1、找到合适的free page run,则分割该free page run,并将剩余的作为新的free page run插入free_page_runs_2、找不到合适的,则在原有的free_page_runs_后面扩展新的free page run结构,使满足所需求的page。扩展前会预先检查确保扩展后不会突破capacity_,扩展的大小最少为2M。扩招再进行分割,满足需求后将剩余的作为新的free page run放入free_page_runs_中去。得到符合要求的pages后,会在page_map_中标注该段pages的用途(详细看代码)。

i.             

ii.             

iii.            Free

·         FreeInternal

根据需要freeptr,对比page_map_知道该段内存的用途,作为largeObject还是run。如果是largeObject,调用FreePages释放pages;如果是run,调用runfree流程FreeFromRunrun的定位通过page_map_base计算得到)

·         FreeFromRun

首先调用FreeSlot,对该run中对应的slot0,清bitmap

如果归还该run已经空了,没有slot被占用,则从non_full_runs_摘除该run,然后清除该runheader,调用FreePages归还pages。如果该run不为空,说明还有其他slot被占用,检查non_full_runs_是否记录过该run。如果一切runfull的,不在non_full_runs_之中,此时将它加入non_full_runs_

·         FreePages

更新对应地址上的page_map_标记为kPageMapEmpty,根据page_release_mode_判断是否要对该领域清0

将释放掉的地址空间构造成一个新的FreePageRun,如果free_page_runs_集合不为空,则尝试着向低地址或者高地址合并,变成新的更大FreePageRun,插入free_page_runs_。此处会releasePages1memset02、标记page_map_),但不会通过madvice置为MADV_DONTNEED,提高该段内存重用时的性能。

iv.            Trim

·         Trim

获得free_page_runs_最尾部的free page run(未使用),memset0或者通过madvice置为MADV_DONTNEED,更新footprinter

i.            Thread Local

·         初始化

Thread构造函数中会构造一个run* 数组rosalloc_runs。数组大小为34,对应于34个级别的run,不过此时的run并不可用,第一次使用的时候才会真正分配一个run。以后从thread local分配时,从rosalloc_runs取出对应级别的run进行分配。

·         Alloc

thread_local_run中调用AllocSlot分配空间。如果第一次分配不到内存,说明是首次调用,或者run已满。如果是run首次调用,refill这个run,如果是run已满,调用MergeThreadLocalFreeBitMapToAllocBitMap函数将thread local free bitmap合并到alloc bitmap中去。

thread local free bitmapthread local runfree的时候才会被置,如果merge后返回为1(即thread local free bitmap被置为1过),说明thread local run被释放过,但是alloc bitmap还未同步,则更新alloc bitmap的信息,重新在这个run上进行分配。这么做的好处是:小额内存使用时候,不需要在共享内存上分配,防止加锁降低性能。

如果mergebitmap显示该run还是full,则重新获得run,并将其作为新的thread local run,在新的thread local run分配slot

·         Free

调用MarkThreadLocalFreeBitMap函数,将该部分内存清0,将thread local bitmap中该slot位置置1

ii.            Bulk Free

·         BulkFree

该函数传进参数为地址数组,函数功能为批量Free

1、 根据传进地址,决定释放run或者释放large object(即释放page,非物理page)。如果释放run,标记bulk free bitmap

2、 如果释放的runthread local run,将bulk free bitmap合并到thread local bitmap中去,如果为普通run,将bulk free bitmap合并到alloc bitmap中去。

3、 如果释放后的run为空并且不为当前使用的run,则free掉该run

4、 如果释放后的run不为空且不为当前使用的run,则将该run插入到non_full_runs中。

 

rosalloc

标签:

原文地址:http://my.oschina.net/boolearner/blog/479909

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!