C++ 内存分配失败,即使内存仍然足够

C++ 内存分配失败,即使内存仍然足够,c++,linux,memory,process,C++,Linux,Memory,Process,我正在Linux(Ubuntu13.04)上工作,目前我有一个问题:为什么内存分配会失败,即使内存仍然足够 我今天编写了一个简单的测试应用程序,在运行这个测试应用程序时遇到了这个问题。下面是我用来进行测试的代码片段: #include <stdio.h> #include <unistd.h> #include <list> #include <vector> #include <string

我正在Linux(Ubuntu13.04)上工作,目前我有一个问题:为什么内存分配会失败,即使内存仍然足够

我今天编写了一个简单的测试应用程序,在运行这个测试应用程序时遇到了这个问题。下面是我用来进行测试的代码片段:

     #include <stdio.h>
     #include <unistd.h>
     #include <list>
     #include <vector>
     #include <strings.h>

     using namespace std;
     unsigned short calcrc(unsigned char *ptr, int count)
     {
        unsigned short crc;
        unsigned char i;

        //high cpu-consumption code
        //implements CRC algorithm: Cylic 
        //Redundancy code              
     }


     void* CreateChild(void* param){
         vector<unsigned char*>  MemoryVector;
         pid_t PID = fork();
         if (PID == 0){
             const int MEMORY_TO_ALLOC =  1024 * 1024;
             unsigned char* buffer = NULL;
             while(1){
                 buffer  = NULL;
                 try{
                     buffer = new unsigned char [MEMORY_TO_ALLOC]();
                     calcrc(buffer, MEMORY_TO_ALLOC );
                     MemoryVector.push_back(buffer);
                 } catch(...){
                     printf("an exception was thrown!\n");
                     continue;
                 } //try ... catch
             } //while  
          } // if pid == 0

      return NULL;
      }

    int main(){
        int children = 4;
        while(--children >= 0){
            CreateChild(NULL);
        };

        while(1) sleep(3600);
        return 0;
    }

可能您的地址空间中没有更多1MB顺序内存页。你有自由空间碎片

在我的测试中,当内存大约为220M时,上面的代码开始抛出异常。从现在起,应用程序似乎无法获得更多的内存,因为TOP命令显示的可用内存仍然保持在210M以上。那么为什么会发生这种情况呢

top
的输出每N秒更新一次(已配置),并且不会真正显示当前状态

另一方面,内存分配非常快


发生的情况是,您的程序占用内存,并且在某个点(当顶部显示200 Mb空闲时)它开始失败。

您正在x86-32上运行,因此您的进程是32位的。即使使用更多内存+交换,它们也会受到地址空间的限制,请运行:

grep “HIGHMEM” /boot/config-`uname -r`
grep “VMSPLIT” /boot/config-`uname -r`
查看内核是如何配置的

也许您的4个子进程仅限于3G,并且正在使用12G+其他进程~700M来达到您看到的数字

编辑:

因此,内核被配置为给每个用户空间进程3G的地址空间,其中一些地址空间将被程序、库和初始运行时内存占用(由于fork而共享)

因此,您有4个孩子分别使用~3G-~12G+~7800万其他程序。一旦孩子们开始报告错误,这将留下大约220米的空闲空间


您可以运行另一个子进程,也可以使用和64/x86-64版本的Ubuntu重新安装,每个进程将能够分配更多内存。

以及一些堆不使用的内存。我同意-可能存在碎片。此外,还不清楚“大约有210M内存”是什么意思。“记忆”在哪里?在系统中?在这个过程中?在swap?@JonWatte中,当系统内存超过210M时,测试应用程序开始抛出异常。我更新了帖子。这不取决于你的系统有多少内存。每个32位进程(我想这是您的情况)都有自己的4GB地址空间。其中几乎有2个进程可以使用(或在某些系统上使用3个)。再也没有了。那么,这个进程到底使用了多少内存?(我不知道如何在linux中检查它)注意,进程本身的可用地址空间实际上可能少于4GB——2GB或3MB是32位进程的典型限制。线程的共享库、可执行文件和堆栈也会占用地址空间。它在使用220M时失败,或者在220M空闲时失败?它是一个32位进程吗?您是否检查了进程是否设置了内存限制(
ulimit
或其他什么?我不知道,我不是linux的家伙)计算机有多少内存和交换空间?@MooingDuck在超过210M可用内存时失败。更新了帖子。第一个是“CONFIG_HIGHMEM64G=y CONFIG_HIGHMEM=y”,第二个是“CONFIG_VMSPLIT_3G=y”@StevePeng,所以答案是您的子进程每个都限于3G。是的,您是对的。如果我在我的应用程序中创建了6个进程,那么在它开始抛出异常之后,其他应用程序会因为内存不足而减慢速度,并且即使使用“free”shell命令也无法启动更多进程。
grep “HIGHMEM” /boot/config-`uname -r`
grep “VMSPLIT” /boot/config-`uname -r`