18

正如我在这里描述的那样,我正在编写一个需要大量内存用于缓存目的的应用程序。现在我正在玩一些 malloc / new 结构来弄清楚我如何实现它。我做了一个奇怪的观察:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
  while(1) {
    char *foo = (char*)malloc(1024);// new char[1024];
    if(foo == NULL) { 
      printf("Couldn't alloc\n");
      fflush(stdout);
      return 0;
    }
  }
  return 0;
}

为什么永远无法达到 printf ?如果我的系统内存不足,则据说 malloc 返回 NULL,如此处所述。但我总是收到 SIGKILL (我正在使用 linux ......)。

4

4 回答 4

25

默认情况下,Linux 通常使用机会性内存分配方案,这意味着内核会给你一个有效的地址,直到第一次使用才会分配。

看:

根据这些回复,您可以使用关闭此功能echo 2 > /proc/sys/vm/overcommit_memory

据我所知,这是在您不一定会使用您分配的所有内存的假设下完成的。我不能说我个人曾经分配过至少一次不接触的空间,所以我很想知道这会如何影响现实生活中的表现......

关于 SIGKILL 失败,您调用的每个 malloc 仍在为每个调用分配一些内存。最终,您可能会用 malloc 开销填充您的内存,从而引起内存不足终止功能的愤怒。仅此一个问题,或者是否过度使用策略仍然分配了所请求空间的一部分,这是一个很好的问题。

于 2013-05-21T16:10:25.093 回答
6

通常,Linux 会根据您的要求分配尽可能多的(虚拟)内存,并且仅在需要时为其分配物理内存。如果系统用完了物理内存,那么它会开始杀死进程以释放一些。

这意味着malloc除非请求是可笑的,否则它将成功,但是您的进程(或其他进程)可能会在使用内存时被杀死。

有关更多详细信息,请参阅手册页malloc及其参考:

默认情况下,Linux 遵循乐观的内存分配策略。这意味着当malloc()返回 non-时NULL,不能保证内存确实可用。如果发现系统内存不足,OOM 杀手将杀死一个或多个进程。更多信息请参见 /proc/sys/vm/overcommit_memory 和 /proc/sys/vm/oom_adj 中的描述proc(5),以及内核源文件 Documentation/vm/overcommit-accounting。

(当然new,除非您使用无投掷版本,否则无论如何都不会返回 null)。

于 2013-05-21T16:13:57.760 回答
4

mallocNULL如果请求的分配无法完成,则返回。但也许您应该尝试从heap分配大量空间。

这里

在 linux 上,调用 malloc() 时出现错误的唯一方法是禁用内存过度使用。在常规的 linux 系统上,这是 malloc() 返回 NULL的唯一方法。如果一个 icecast 进程达到了这一点,它无论如何都搞砸了,它将无法做任何有意义的事情:任何源读取都会失败(refbuf alloc),任何日志打印也会失败(printf 也使用 malloc),所以它也可以放弃并调用 abort()。

于 2013-05-21T16:00:46.527 回答
-1

如果操作系统让您的程序运行那么久,Malloc 将返回 NULL。但是在 malloc 有机会运行操作系统之前,它会杀死您的进程。

就像如果它检测到您正在写入分配给您的进程的外部内存页面,它会杀死您的进程。

于 2013-05-21T16:08:29.700 回答