Linux动态内存管理学习

 

堆的申请:

堆空间在malloc以后,才会生成,堆的最小单位为chunk

chunk是什么:

chunk结构:(chunk像是一个双向链表的结构)

虽然chunk由一个统一的结构体声明,但是在被使用时和空闲时却又有两种不同的状态.

ptmalloc中每个chunk的大小是有固定的格式的.其依赖平台的size_t长度,32位为4字节,64位为8字节(也可能4字节)

所以:

64位平台下最小的chunk0x20(8+8+8+8)

32为平台下最小的chunk0x10(4+4+4+4)

struct
malloc_chunk{

INT prev_size: 如果前一个chunk是空闲的,那么该字段表示前一个chunk的大小,如果前一个chunk不空闲,那么无意义.

当上一个chunk正在使用时,可以复用下一个chunkprev_size(引起漏洞例如:单字节溢出等.)

prev_size复用,记录的内容:

如果前一个chunk为空闲:prev_size = 前一个chunk的大小,所以:

获得前一个chunk的地址: 当前chunk的地址 - prev_size

如果前一个chunk被使用:prev_size = 前一个chunk的内存内容:

前一个chunk可以被使用

 

INT size: 当前chunk大小,并记录了当前chunk和前一个chunk的一些属性(二进制的后三位A,M,P
原因是因为需要地址对齐,所以第三位也无法修改)

A:

M:判断是否空闲

P: prev_inuse:记录前一个chunk是否被分配

struct malloc_chunk* fd:
记录了下一个被freechunk
,
是一个结构体指针(基于当前chunk),相当于结构体中指向上一个节点

struct malloc_chunk* bk: 记录了上一个被freechunk
,
是一个结构体指针(基于当前chunk),,相当于结构体中指向下一个节点

struct malloc_chunk* fd_nextsize:
记录了下一个被freechunksize ,是一个结构体指针

struct malloc_chunk* bk_nextsize:
记录了上一个被freechunksize ,是一个结构体指针

}

64位平台下,一个使用中的chunk大小计算公式(inuse_size):用户申请的大小+16(chunk)(prev_size+size)-8(下一个chunk8,prev_size的复用)

chunk是堆的最小操作单元,chunk的结构也是堆的结构.

chunk的结构体叫做malloc_chunk

 

在运行中被malloc分配的内存我们称为一个chunk

堆的释放:

chunkfree以后会被加入空闲管理列表(堆被释放时的)

free以后的chunk 去了bins

 

堆释放后的管理:

堆释放后会被添加到相应的bins里进行管理,

这里涉及结构体malloc_state

(这里借用dalao的图,侵删)

 

bins是什么:

bins的管理机制靠双链表进行管理

glibc malloc分配了多个bins,目的是为了方便查找空闲的chunk

glibc提供了2个数组,一个是fastbinY,还有bins,其中bins英文翻译是垃圾桶,就是存放没有被freechunk

根据chunk的大小和处于的状态,分别将其放在不同的bins:
unsorted bin
small bins large
bins

fastbins(fastbinsY):为单链表管理

主要用于提高小内存的分配率,对于较小的chunk分配请求,首先会查找fastbins中是否存在所需大小的chunk存在(精确查找),如果存在,就直接返回

fastbins是由单链表进行管理存储的.

拥有10个元素的数组,用于存放每个fast chunk的链表头指针,

所以fast bins最多包含10fast chunk的单向链表(仅指向下一个chunk),

fastbins无论在free 还是inuse 它的inuse位一直为1,

这也是好多fastbins最后一个位都有一个1的原因代表inuse

fastbins什么情况下使用:

size_sz4B的平台:chunk大小都是8B的倍数,小于64Bchunk 16B 24B 32B 40B 48B 56B 64B

size_sz8B的平台:chunk大小都是16B的倍数,小于128Bchunk 32B 48B 64B 80B 96B 112B 128B

7个大小的chunk的空闲链表

fastbin可以看作是smallbin的一小部分cache,默认情况下知识cachesmallbins的前七个大小的空闲chunk
16B 24B 32B 40B 48B 56B 64B
七个

 

bins:1unsorted bin,62small bins,63large
bins
. 结构全都为双链表管理

unsorted bin: 可以看作是smallbinslargebinscache,

所有的chunk要回收时,都要先放到unsortedbin,

分配时,如果在unsortedbin中没有合适的chunk,就会把unsortedbin中的所有chunk分别加入到所属的bins,然后在bins中分配合适的chunk,

bins数组中的元素bin[1]用于存储unsortedbinchunk链表头

small bins:管理一些小的chunk

每个smallbin中的chunk大小与binindex有以下关系:chunk_size = 2*size_sz*index

smallbins什么情况下使用:

size_sz4B的平台:smallbins中的chunk大小都是8B的倍数,最大的chunk504B,最小为16B,所以一共62bin大小分别为16,24,32,40,48,...504

size_sz8B的平台:smallbins中的chunk大小都是16B的倍数,最大的chunk504B,最小为16B,所以一共62bin大小分别为32,48,64,...1008

62个大小的chunk的空闲链表

large bins:管理比较大的chunk

分成了6bin每组bins的数量为32 16 8
4 2 1
加起来为63

第一个large bin的初始大小为512B,32bin,中间间隔(公差)64B,满足如下关系:chunk_size = 512+64*index

第二个large bin的起始大小为第一个bin结束的chunk大小,满足如下关系:chunk_size = 512+64*32+512*index(32为第一个large bin32bin)

largebins什么情况下使用:

size_sz4B的平台:大小大于等于512B

size_sz8B的平台:大小大于等于1024B

每组bins公差依次为64B,512B,4096B,32768B,262144B

63哥大小的chunk的空闲链表

 

堆的再次申请:

 

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注