我猜clang AddressSanitizer 失败了,因为存在合法泄漏。所以我的回答忽略了这一点:
备择方案:
- 正如您已经发现的那样,禁用过度使用行为:这将影响其他进程并且需要 root。
- 在禁用 oom 杀手的 docker 映像中运行您的应用程序:这不会影响其他进程,但需要 root 才能安装 docker(尽管这是我最喜欢的解决方案)。
- 在 malloc 之后写入:分配大量内存可能需要很长时间,并且您的进程仍然可能由于其他正在运行的进程而被杀死,但不需要 root。
- 使用 ulimit -v 来限制取决于机器的内存量:这也不需要 root 但你的进程可能会被杀死。
第三种选择的代码(用于 linux):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf resume_malloc;
void handle_malloc_error(int sig)
{
longjmp(resume_malloc, sig);
}
void *memalloc(size_t sz) {
void *p = 0;
int sig = setjmp(resume_malloc);
if ( sig == 0 ) {
p = malloc(sz);
signal(SIGSEGV, &handle_malloc_error);
memset(p, 0, sz);
} else {
p = 0;
}
signal(SIGSEGV, SIG_DFL);
return p;
}
int main(int argc, char *argv[])
{
size_t sz = 160L * 1024 * 1024 * 1024L;
void *p;
for (int i=0; i < 100; i++) {
printf("size: %lu\n", sz);
p = memalloc(sz);
if ( p == 0 ) {
printf("out of memory\n");
break;
}
sz *= 2;
}
}