分类: LINUX
2013-05-22 23:18:56
malloc()分配内存的时候,可能调用brk(),也可能调用mmap2()。
分配:1、即分配一块小型内存(小于或等于128kb),malloc()会调用brk()调高断点(brk是将数据段(.data)的最高地址指针_edata往高地址推),分配的内存在堆区域,
2、当分配一块大型内存(大于128kb),malloc()会调用mmap2()分配一块内存(mmap是在进程的虚拟地址空间中(一般是堆和栈中间)找一块空闲的)(一般是堆和栈中间区域)。
malloc分配的内存只分配了虚拟地址空间,当在第一次访问的时候,发生缺页中断,操作系统负责分配物理内存,并建立虚拟内存和物理内存之间的映射关系。
释放:同样的,
1、munmap释放内存映射方式分配的内存之后,内存马上会被系统收回(不会产生内存碎片),
2、释放brk分配的一块内存,并不会马上被系统回收(因为移动_edata指针时,只有最高位对应的虚拟内存释放了,才能往前移动,当然,这块内存可以被再分配了。参考http://blog.163.com/xychenbaihu@yeah/blog/getBlog.do?fromString=blogmodule),glibc会保留它以供下一次malloc()使用,glibc有一套自己的内存管理机制。
这里演示一下malloc()使用brk()和mmap2():
/* * file:t_malloc.c */
#include
#include
#include
int main(int argc, char *argv)
{
char *brk_mm, *mmap_mm;
("-----------------------\n");
brk_mm = (char *)malloc(100); //小于128kb个字节 调用brk
memset(brk_mm, '\0', 100);
mmap_mm = (char *)malloc(500 * 1024); //500kb>128kb 调用mmap2()
memset(mmap_mm, '\0', 500*1024);
free(brk_mm); //不会立马释放内存,而是由glibc做内存管理
free(mmap_mm); //调用munmap,会立即释放内存(非堆上的内存)
("-----------------------\n");
return 1;
}
#gcc –o t_malloc t_malloc.c
#strace ./t_malloc
write(1, "-----------------------\n", 24-----------------------) = 24
brk(0) = 0x85ee000
brk(0x860f000) = 0x860f000 //malloc(100)
mmap2(NULL, 516096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7702000 //malloc(5kb)
munmap(0xb7702000, 516096) = 0 //free(), 5kb
write(1, "-----------------------\n", 24-----------------------) = 24
通过malloc()分别分配100bytes和5kb的内存,可以看出其实分别调用了brk()和mmap2(),相应的free()也是不回收内存和通过munmap()系统回收内存。