#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<pthread.h>
#define BLOCKSIZE 1024*1024
// #define BLOCKSIZE 4096
int main (int argc, char *argv[])
{
void *myblock = NULL;
int count = 0;
while (1)
{
myblock = malloc(BLOCKSIZE);
if (!myblock){
puts("error"); break;
}
memset(myblock,1, BLOCKSIZE);
count++;
}
printf("Currently allocated %d n",count);
printf("end");
exit(0);
}
当块大小为 1024*1024 时。 一切都很好。 Malloc 返回 NULL,循环中断。程序打印文本并退出。
当块大小为 4096 时Malloc 从不返回空程序崩溃。=>内存不足,被内核杀死。为什么?
漆黑一片,你很可能会被OOM杀手吃掉。
Linux有一个叫做OOM杀手的东西,当它发现内存分配非常繁重时,它会四处游荡。选择终止哪个进程是基于每个进程的某些属性(例如,分配大量内存的进程是主要候选进程(。
它这样做,部分原因是其乐观的内存分配策略(无论设备上是否有足够的备用内存,它通常会为您提供地址空间,这称为过度使用(。
在这种情况下,一次分配 1M 时,分配很可能在 OOM 杀手找到您之前失败。使用 4K,您可以在分配例程决定您已经受够之前被发现。
如果需要,可以将 OOM killer 配置为让您独自一人,方法是将调整值 -17
写入 procfs
中的oom_adj
条目。除非您知道自己在做什么,否则这是不可取的,因为它会使其他(也许更重要的(流程面临风险。从-16
到+15
的其他值调整选择过程的可能性。
您还可以通过将vm.overcommit_memory=2
写入/etc/sysctl.conf
来完全关闭过度使用,但这同样会在您的环境中带来问题。