1

在我的 C 程序中,根据用户的输入,将为给定的模拟分配内存。我面临的最初问题是用户可以要求分配大量数字,但 malloc() 永远不会失败,直到内存不足然后程序崩溃。

我调查了这背后的逻辑,现在它对我来说很有意义,请参阅 [ 1 ][ 2 ]。此处给出的一种可能的解决方法“ SIGKILL while allocating memory in C++ ”建议设置overcommit_memory/proc/sys/vm/overcommit_memory从 0 到 2。

这从一方面解决了问题。但由于我正在使用,-fsanitize=address我从消毒剂中得到错误。

有没有更好的解决方案?

4

1 回答 1

0

我猜clang AddressSanitizer 失败了,因为存在合法泄漏。所以我的回答忽略了这一点:

备择方案:

  1. 正如您已经发现的那样,禁用过度使用行为:这将影响其他进程并且需要 root。
  2. 在禁用 oom 杀手的 docker 映像中运行您的应用程序:这不会影响其他进程,但需要 root 才能安装 docker(尽管这是我最喜欢的解决方案)。
  3. 在 malloc 之后写入:分配大量内存可能需要很长时间,并且您的进程仍然可能由于其他正在运行的进程而被杀死,但不需要 root。
  4. 使用 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;
   }
}
于 2016-09-28T14:38:39.153 回答