malloc 在不同机器上的行为不同
当在不同的机器上运行一个试图超过 RSS 的程序时,我看到完全不同的行为。代码类似于:
...
char** s = (char**)malloc(10000*sizeof(char*));
for (i = 0; i < 10000; i++){
s[i] = (char*)malloc(1000*1000*sizeof(char));
if (s[i] == NULL) {
printf("cannot allocate memory for s[%d]",i);
exit(1);
}
}
int j = 0;
while(1){
for (i = 0; i < 10000; i++){
for (j = 0; j < 1000*1000; j++) {
s[i][j] = 1;
}
if ((i % 100) == 0) printf("i = %d\n", i);
}
}
for (i = 0; i < 10000; i++)
free(s[i]);
free(s);
...
上面的代码尝试使用 malloc 分配大约 10GB 的内存。我尝试在 linux 内核 2.6 上运行此代码的前两台机器,最后一台运行 linux 内核 2.4。以下是我在这些机器上看到的行为:
Machine1:使用内存过量分配来分配内存,但在 while 循环中为内存位置赋值时,它只分配 RSS 允许的数量。因此,当打印 i=3800 时,OOM Killer 会杀死该进程,这大约是该机器拥有的 4GB 内存。
Machine2:使用内存过量分配来分配内存,并且 while 循环永远持续下去,从虚拟内存中分配页面。打印 i = 3800 后,该过程会变慢一些,这是正常的。
machine3:这台机器只有2GB内存。甚至无法分配内存。似乎未设置过度提交或内核 2.4 不支持使用 malloc 分配虚拟机页面!因此,在第一个 for 循环中,它在为 i = 2138 分配内存时退出,
我想要的操作是 machine2 中发生的操作。有谁知道必须设置哪些(内核?)选项才能允许操作系统使用 malloc 分配虚拟内存页面并在所需内存超过 RSS 时启动分页?
谢谢
I see totally different behavior when running a piece of program that tries to exceed RSS on different machines. The code is something like:
...
char** s = (char**)malloc(10000*sizeof(char*));
for (i = 0; i < 10000; i++){
s[i] = (char*)malloc(1000*1000*sizeof(char));
if (s[i] == NULL) {
printf("cannot allocate memory for s[%d]",i);
exit(1);
}
}
int j = 0;
while(1){
for (i = 0; i < 10000; i++){
for (j = 0; j < 1000*1000; j++) {
s[i][j] = 1;
}
if ((i % 100) == 0) printf("i = %d\n", i);
}
}
for (i = 0; i < 10000; i++)
free(s[i]);
free(s);
...
The above code tries to allocate around 10GB of memory using malloc. The first two machines I tried this code on run on linux kernel 2.6 and the last one runs linux kernel 2.4. Here are the behaviors I see on these machines:
Machine1: the memory is allocated using memory overcommit, but when assigning values to the memory locations in the while loop, it only allocates as much as RSS allows. Thus OOM Killer kills the process when i=3800 is printed which is around 4GB of memory this machine has.
Machine2: memory is allocated using memory overcommit and the while loop goes on forever, allocating pages from virtual memory. The process goes a bit slower after i = 3800 is printed which is normal.
machine3: this machines has only 2GB of memory. The memory cannot even be allocated. Seems like the over commit is not set or kernel 2.4 does not support allocating virtual machine pages using malloc! Thus in the first for loop it exits while allocating memory for i = 2138
My desired action is the one happening in machine2. Does anyone know which (kernel?) options has to be set to allow OS to allocate virtual memory pages using malloc and start paging while the required memory exceeds RSS?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您将无法在 32 位计算机上分配 100GB 并使用常规指针对其进行寻址,而您的代码似乎使用的是常规指针。事实上,机器 1 在达到大约 4GB 时终止进程,而机器 2 并不能强烈表明机器 2 正在运行 64 位操作系统。
You won't be able to allocate 100GB on a 32-bit machine and address it using regular pointers, which is what your code seems to use. The fact that machine 1 terminates the process when it hits approx 4GB and machine 2 doesn't strongly suggests that machine 2 is running a 64-bit OS.