不管内存在哪里被分配,用什么方法分配,用户请求分配的空间在ptmalloc中都使用一个chunk来表示。用户调用free()函数释放掉的内存也并不是立即就归还给操作系统,相反,它们也会被表示为一个chunk,ptmalloc使用特定的数据结构来管理这些空闲的chunk。
对于64位操作系统,每个chunk的大小均按16字节对齐;一个chunk的最小长度为32字节;用户请求分配的长度加8字节然后按照16字节对齐,这就是ptmalloc为用户分配的chunk的大小。
对于分配给用户的chunk,在内存中的样子大概如下所示:
表示当前chunk大小的最后三位:A表示该chunk是否属于主分配区(main arena);M表示该chunk是否通过mmap分配;P表示前一个chunk是否正在使用。
对于调用free()函数归还给ptmalloc的chunk,在内存中的样子大概如下图所示:
对于fast_bin/small_bin中的chunk,利用用户数据空间的16个字节存储指向前后chunk的指针。
对于large_bin中的chunk,还会再多利用16个字节,用于双向链接指向不同长度的chunk。
另外,从上图可以看出,为什么一个chunk的最小为32字节了。
一段示例代码,从用户请求分配的空间查看对应chunk的大小:
void test_chunk()
{
char * pTmp1 = NULL;
// 申请 1字节长度的空间
pTmp1 = (char*)malloc(1);
// malloc返回的地址往前8个字节为chunk大小的起始地址
char * pChunkSize = pTmp1 - 8;
// 末尾3位为标志位
size_t nChunkSize = *((size_t*)pChunkSize) & (~(0x7));
printf("tmp1 chunk size: %d\n", nChunkSize);
char * pTmp2 = NULL;
pTmp2 = (char*)malloc(1053);
pChunkSize = pTmp2 - 8;
nChunkSize = *((size_t*)pChunkSize) & (~(0x7));
printf("tmp2 chunk size: %d\n", nChunkSize);
free(pTmp1);
free(pTmp2);
return ;
}
上述代码的执行结果为:
tmp1 chunk size: 32
tmp2 chunk size: 1072
简单说明:
申请1字节长度的空间,ptmalloc实际返回的chunk的长度为32字节,间接也证明了chunk的最小长度为32字节。
申请1053字节长度的空间,ptmalloc在此基础上需要再加8字节,然后按16字节对齐,因此chunk大小为1072字节。