-->
当前位置:首页 > DayDayUp > 正文内容

ptmalloc堆内存管理

Luz4年前 (2020-01-31)DayDayUp3708

堆内存的函数

malloc:

    向系统申请一块内存

free:

    释放一块内存

realloc:

    重新分配堆内存,用于堆空间不足需要重新分配大小且需要保留原数据的情况 


chunk

在Glibc的堆内存管理中,chunk是堆内存分配的基本的单位,它表示堆内存中连续的内存单元。


示意图:

 

  • chunk指针指向一个chunk的开始处,而mem指针才是真正分配给用户的储存空间。

  • chunk的第二个域的最低一位P表示前一个chunk是否是在使用当中(0代表前一个空闲,1代表在使用当中)。
    当P为0时,此时prev_size才有效,第一个域表示的是前一个chunk的size,可以通过这个值取到前一个chunk的开始地址;当P为1时,表示前一个chunk在使用当中,prev_size无效。
    ptmalloc分配的第一个chunk总是将P设为1,以防止程序引用到不存在的区域。

  • chunk第二个域倒数第二位M(0表示是从mmap映射区域分配的,1表示heap区域分配)

  • chunk第二个域倒数第三位A(1表示主分配区,0非主分配区)

  • 当chunk空闲时,user_data区域储存了4个指针。
    指针fd指向后一个空闲的chunk;
    指针bk指向前一个空闲的chunk;
    fd_nextsize以及bk_nextsize两个指针用于加快在large bin中查找最近匹配的空闲chunk

  • chunk利用标志来管理使用和空闲的内存,减少了内存归还所带来的系统消耗,并且在一个未使用的chunk中,它的prev_size部分是可以被紧挨的上一个使用的chunk空间复用的。

bins

ptmalloc将相似大小的chunk用双向链表链接起来,这样的一个链表就被叫做bin,ptmalloc一共维护了128个bin,并用一个数组来储存这些bin


indexunsorted bin(0)small bin(1-63) 62个large bin(64-127)64个
size88+8*index



  • 数组第一个是unsorted bin,ptmalloc在合并空闲的chunk时会放入,如果用户释放的chunk大于max_fast或者fast bins中空闲的chunk合并之后都会放入unsorted bin中。ptmalloc在fast bins中没有找到合适的chunk就会进入unsorted bins中查找,如果还是没有找到,就会把unsorted bin汇总的chunk加入到bins当中。当用户使用malloc分配内存时,如果需要分配的大小比freed chunk的大小更小,就会将freed chunk切割成两部分,返回符合申请大小的一部分,另一部分存入unsorted bin。这样看来,unsorted bin类似于bins中的一个缓冲区。

  • 数组的2到64个bin被称为small bins,同一个small bin中的chunk大小相同,两个相邻的small bin相差8字节;

  • 后面64个bin称为large bins,这里面的每一个bin都是一个范围内的chunk并且是按大小序排列好的;

  • 与small bin和fast bin不同的是,每一个large bin中的freed chunk的大小不一定相等,其只是表示一个范围,在前32个large bin中,以64字节为步长,即第一个large bin中的chunk大小为512~575字节,第二个large bin中的free chunk大小为576~639字节。紧随其后的16个large bin依次以512字节步长为间隔;之后的8个bin以步长4096为间隔;再之后的4个bin以32768字节为间隔;之后的2个bin以262144字节为间隔;剩下的chunk就放在最后一个large bin中。

  • fast bins

    引入它是因为在分配时可能会经常申请和释放一些很小的空间,分配器合并之后又需要分割,这样太过低效,故而在不大于max_fast(默认值是64B)的chunk释放后会先被放到fast_bins中,不去改变他们的P标志位,所以他们无法合并,在小于等于max_fast时首先在fast_bins中查找相应的空闲块。

  • Top chunk
    这是一开始所划分出来的一个大空闲内存,可以看做是heap的一个边界,如果bins之后还没有满足的chunk,那么通过Top chunk来划分一个新的chunk给用户

  • mmaped chunk
    当top chunk都不能满足时,通过mmap将页映射到进程空间中,这样的chunk被free时候直接解除映射归还给系统。

  • last remainder
    当所请求的chunk是一个小空间的,但是在small bins中又没有合适的chunk,那么从last remainder chunk中分裂出两个chunk,一个给用户,一个变成新的last remainder chunk。




发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。