【问题标题】:Heap size limitation in CC 中的堆大小限制
【发布时间】:2010-12-25 14:24:58
【问题描述】:

我对 C 程序的程序执行布局图中的堆有疑问。

我知道所有动态分配的内存都分配在动态增长的堆中。但我想知道 C 程序的最大堆大小是多少??

我只是附加了一个示例 C 程序...在这里我尝试为字符串分配 1GB 内存,甚至执行 memset ...

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

    int main(int argc, char *argv[])
    {
       char *temp;
       mybuffer=malloc(1024*1024*1024*1);

       temp = memset(mybuffer,0,(1024*1024*1024*1));

       if( (mybuffer == temp) && (mybuffer != NULL))
       printf("%x - %x\n", mybuffer, &mybuffer[((1024*1024*1024*1)-1)]]);
       else
       printf("Wrong\n");

       sleep(20);
       free(mybuffer);
       return 0;
    }

如果我一次在 3 个实例中运行上述程序,那么 malloc 应该至少在一个实例中失败 [我觉得如此] ...但 malloc 仍然是成功的。

如果成功,我能否知道操作系统如何处理 3GB 动态分配的内存。

【问题讨论】:

    标签: c linux heap-memory


    【解决方案1】:

    您的机器很可能在 RAM 上 overcomitting,并且在您实际写入之前不会使用内存。分配后尝试写入每个块,从而强制操作系统确保有真正的 RAM 映射到返回的地址 malloc()

    【讨论】:

    • +1 每页写一个字节就可以强制提交内存了。
    • 我确实在分​​配的动态内存上尝试了 memset ...当我运行 2 个实例时似乎没问题
    • 写入不会改变任何东西,只会强制内核开始交换。当交换和 RAM 已满时,Linux 内核开始终止进程​​ (xenotime.net/linux/doc/swap-mini-howto.txt)。所以据我所知,你永远不会看到 malloc 返回的 NULL,因为系统的物理内存不足。但是,您可能会得到 malloc 返回的 NULL,因为您的进程使用了​​“太多”的虚拟地址空间。这里解释得很好:duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
    【解决方案2】:

    来自 linux malloc 页面,

    BUGS
           By  default,  Linux  follows  an optimistic memory allocation strategy.
           This means that when malloc() returns non-NULL there  is  no  guarantee
           that  the  memory  really  is available.  This is a really bad bug.  In
           case it turns out that the system is out of memory, one  or  more  pro‐
           cesses  will  be  killed  by the infamous OOM killer.  In case Linux is
           employed under circumstances where it would be less desirable  to  sud‐
           denly lose some randomly picked processes, and moreover the kernel ver‐
           sion is sufficiently recent, one can  switch  off  this  overcommitting
           behavior using a command like:
    
               # echo 2 > /proc/sys/vm/overcommit_memory
    
           See  also  the  kernel  Documentation  directory,  files vm/overcommit-
           accounting and sysctl/vm.txt.
    

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 我确实了解虚拟内存...我只是留下有关我的内存详细信息的信息
      • 嗯,你问为什么当你有 1GB 的 RAM 时分配 3GB 不会失败。假设您实际上是通过 malloc 使用 3GB 内存。您实际使用的是 3GB 的虚拟页面。当系统内存不足时,它使用交换作为备份来将先前分配的页面存储在磁盘上,从而为新页面释放一些 RAM。看看这个:apollo.lsc.vsc.edu/metadmin/references/sag/x1752.html
      • 但是我的swap利用率是0%是什么意思?
      • 这意味着系统根本没有使用交换。但就像 unwind 所说,调用 malloc 实际上并没有提交内存。页面是惰性分配的,这意味着系统只有在您访问它(读取或写入)时才会为您提供页面。
      • 当我说根本不使用交换时,我的意思是还没使用交换
      【解决方案4】:

      Malloc 将分配内存,但不会写入任何内存。因此,如果虚拟内存可用,那么它将成功。只有当你向它写入内容时,才需要将真正的内存分页到页面文件。

      Calloc 如果内存服务正确(!)在返回之前将零写入分配内存的每个字节,因此需要在那里分配页面。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-31
        • 2011-01-29
        • 2010-09-11
        • 1970-01-01
        • 2020-09-05
        • 2011-01-19
        • 1970-01-01
        相关资源
        最近更新 更多