c语言头文件malloc,头文件malloc.h:函数 mallopt()的选项

下面以一个例子来说明内存分配的原理:

情况一、malloc小于128k的内存,使用brk分配内存,将_edata往高地址推(只分配虚拟空间,不对应物理内存(因此没有初始化),第一次读/写数据时,引起内核缺页中断,内核才分配对应的物理内存,然后虚拟地址空间建立映射关系),如下图:

1、进程启动的时候,其(虚拟)内存空间的初始布局如图1所示。

其中,mmap内存映射文件是在堆和栈的中间(例如libc-2.2.93.so,其它数据文件等),为了简单起见,省略了内存映射文件。

_edata指针(glibc里面定义)指向数据段的最高地址。

2、进程调用A=malloc(30K)以后,内存空间如图2:

malloc函数会调用brk系统调用,将_edata指针往高地址推30K,就完成虚拟内存分配。

你可能会问:只要把_edata+30K就完成内存分配了?

事实是这样的,_edata+30K只是完成虚拟地址的分配,A这块内存现在还是没有物理页与之对应的,等到进程第一次读写A这块内存的时候,发生缺页中断,这个时候,内核才分配A这块内存对应的物理页。也就是说,如果用malloc分配了A这块内容,然后从来不访问它,那么,A对应的物理页是不会被分配的。

3、进程调用B=malloc(40K)以后,内存空间如图3。

情况二、malloc大于128k的内存,使用mmap分配内存,在堆和栈之间找一块空闲内存分配(对应独立内存,而且初始化为0),如下图:

4、进程调用C=malloc(200K)以后,内存空间如图4:

默认情况下,malloc函数分配内存,如果请求内存大于128K(可由M_MMAP_THRESHOLD选项调节),那就不是去推_edata指针了,而是利用mmap系统调用,从堆和栈的中间分配一块虚拟内存。

这样子做主要是因为:

brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的,这就是内存碎片产生的原因,什么时候紧缩看下面),而mmap分配的内存可以单独释放。

当然,还有其它的好处,也有坏处,再具体下去,有兴趣的同学可以去看glibc里面malloc的代码了。

5 、进程调用D=malloc(100K)以后,内存空间如图5;

6 、进程调用free(C)以后,C对应的虚拟内存和物理内存一起释放。

7、进程调用free(B)以后,如图7所示:

B对应的虚拟内存和物理内存都没有释放,因为只有一个_edata指针,如果往回推,那么D这块内存怎么办呢?

当然,B这块内存,是可以重用的,如果这个时候再来一个40K的请求,那么malloc很可能就把B这块内存返回回去了。

8、进程调用free(D)以后,如图8所示:

B和D连接起来,变成一块140K的空闲内存。

9、默认情况下:

当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)。在上一个步骤free的时候,发现最高地址空闲内存超过128K,于是内存紧缩,变成图9所示。

头文件

/usr/include/malloc.h

int mallopt (int __param, int __val);

参数 __param的取值范围:-8<=param<=-1 || 1<=param<=4 如下:

#define M_TRIM_THRESHOLD -1

#define M_TOP_PAD -2

#define M_MMAP_THRESHOLD -3

#define M_MMAP_MAX -4

#define M_CHECK_ACTION -5

#define M_PERTURB -6

#define M_ARENA_TEST -7

#define M_ARENA_MAX -8

#ifndef M_MXFAST

# define M_MXFAST 1 /* maximum request size for "fastbins" */

#endif

#ifndef M_NLBLKS

# define M_NLBLKS 2 /* UNUSED in this malloc */

#endif

#ifndef M_GRAIN

# define M_GRAIN 3 /* UNUSED in this malloc */

#endif

#ifndef M_KEEP

# define M_KEEP 4 /* UNUSED in this malloc */

#endif

Table 1. mallopt() Parameters Mapped to Environment Variables

mallopt() param选择

bash环境变量

value默认推荐值

备注

M_TRIM_THRESHOLD

MALLOC_TRIM_THRESHOLD_

128KB

-1U disables

M_TOP_PAD

MALLOC_TOP_PAD_

0

M_MMAP_THRESHOLD

MALLOC_MMAP_THRESHOLD_

128KB

0 disables

M_MMAP_MAX

MALLOC_MMAP_MAX_

64

0 disables

函数返回值1表示成功,0表示失败并修改全局变量errno;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值