一、背景
最近读《程序员的自我修养——链接、装载和库》(俞甲子等著)一书时,看到书中一个很有意思的例子:堆的最大申请数量(原书P168,6.4.3),原来从来没有考虑过这个问题,在此处记录学习一下。
二、问题引入
Linux下虚拟地址空间分配给进程的是3GB,Windows默认是2GB(操作系统为32位),然而程序真正能够使用到的有多少则要根据机器而异了。我们在编程的时候经常会使用到malloc()
函数申请地址空间,但malloc()
最大可以申请到多少内存也并不清楚。
三、问题解决
那么,问题来了,你能写个小程序来回答上述问题么?
#include <stdio.h>
#include <stdlib.h>
unsigned int maximum = 0;
int main(void)
{
unsigned blocksize[] = {1024 * 1024, 1024, 1};
void *block;
int i, count;
for(i = 0; i < 3; i++) {
for(count = 1; ; count++) {
block = malloc(maximum + blocksize[i] * count);
if (block) {
maximum = maximum + blocksize[i] * count;
free(block);
} else {
break;
}
}
}
printf("maximum malloc size = %u bytes.\n", maximum);
}
下面是我在自己的机器上(VMware中的Ubuntu)测试的结果:
-> % ./a.out
maximum malloc size = 1295646688 bytes.
-> % ./a.out
maximum malloc size = 1281228531 bytes.
-> % ./a.out
maximum malloc size = 1280977131 bytes.
-> % ./a.out
maximum malloc size = 1281183027 bytes.
-> % ./a.out
maximum malloc size = 1281179347 bytes.
四、结论和总结
可见,大概有1.2G左右空间可用,且每次执行程序时结果都会稍有不同。那么malloc()
的最大申请数量会受到哪些因素的影响呢?
其实,操作系统版本、程序本身大小、乃至的动态/共享库数量和大小、程序栈数量和大小等都会对其造成影响,甚至有些操作系统使用了一种叫做随机地址空间分布的技术(主要是出于安全考虑,防止程序受恶意攻击),使得进程的堆空间变小。
有兴趣的朋友不妨在自己电脑上试一下,引申出来的细节问题可要一探究竟哦!