一 .问题引出
以下程序执行后占用内存近1G。。。
-
int times = 10000;
-
int i = 0;
-
char *alloc[times];
-
for(i = 0; i < times; i++)
-
{
-
alloc[i] = (char*)malloc(100000);
-
memset(alloc[i], 1, 100000);
-
}
-
-
//for(i = 0; i < times; i++)
-
for(i = 0; i < times - 1; i++)
-
{
-
free(alloc[i]);
-
}
-
while(1)
-
sleep(10);
-
return 0
原因:因为在malloc申请内存的过程中(小于128K,用brk方式分配内存;否则mmap方式),数据段的高地址指针
_edata一直在后移(向高地址移动)。但在释放空间的时候,由于高地址处的空间并没有释放,因此导致堆空间并没有被压缩,因此程序占用近1G的空间。如果循环free的语句替换为注释的那条语句,则没有这个问题。
----------------------------------------------------------------------------------------------------------------------------------------------------
下面这个程序也占内存近1G。。。。
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <stdio.h>
-
#include <string.h>
-
int main()
-
{
-
int times = 20000;
-
char* small[times];
-
char* big[times];
-
for(int j=0; j<1; j++)
-
{
-
for(int i=0; i<times; i++)
-
{
-
big[i] = (char*)malloc(50000);
-
memset(big[i], 1, 50000);
-
small[i] = (char*)malloc(1);
-
memset(small[i], 1, 1);
-
}
-
for(int i=0; i<times; i++)
-
{
-
free(small[i]);
-
free(big[i]);
-
}
-
}
-
//char *alloc = (char*)malloc(2000);
-
//free(alloc);
-
while(1)
-
{
-
sleep(10);
-
}
-
return 0;
-
}
原因:程序在malloc时会根据申请空间的大小执行不同的分支(fastbin,bins,largebin)。
fastbin:申请空间小于80Bytes时,如上面small数组
bins:申请空间在80Byte~~128K
largebin:申请空间大于128K时,采用mmap方式
同时在free的时候操作也不一样。
对于fastbin来说,free()小空间(如small[i])时直接连接到fastbin list上,同时使用标志位不改,仍为1,以便下次申请时直接拿走(这样效率高)。
对于big[i]的空间来说,先放到unsorted list上缓存,然后根据需要在放到相应的bin上。
因此对于上面的程序,虽然对所有空间都执行了free操作,但是small[i]所占空间的标志位仍为1,而big[i]
它试图合并相邻的块,但是和它相邻的块的使用位还是 1 ,所以它不能把相邻的块合并。所以使用的堆无法压缩。
如果在外循环后面再分配 2000 字节然后释放的话,所有内存将全部清空。这是因为在申请 2000 字节的时候,由 malloc 的第二步,程序会先调用 consolidate ,即把所有的 fastbins 清空,同时把相邻的块合并起来,等到所有的 fastbins 清空的时候,所有的块也被合并去来了,然后调用 free2000 字节的时候,这块被将被合并起来 ,成为 topchunk ,并且大小远大于 64k ,所有堆将会收缩,内存归还给系统。
相关参考如下:
1、框架介绍
http://blog.csdn.net/ugg/article/details/4344247
2、源码分析
3、概要
http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201210975312473/
4、FreeBSD-7 内核mallc源码分析(可对比查看)
http://blogimg.chinaunix.net/blog/upfile2/080101160701.pdf
5、内存分配方式介绍
http://blog.csdn.net/ugg/article/details/4344522
阅读(1575) | 评论(0) | 转发(0) |