即使有足够的内存,内存分配也会失败

时间:2013-09-20 16:07:01

标签: c++ linux memory process

我正在使用Linux(完全是ubuntu 13.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;
    }

在我的测试期间,当 220M RAM可用时,上面的代码开始抛出异常。从那一刻起,看起来应用程序无法再获得更多内存 因为TOP命令显示的空闲内存仍然高于210M。那为什么会发生这种情况呢?

更新
1.软件&amp;&amp;硬件信息
   RAM 4G ,交换在 9G 字节左右。运行“uname -a”给出:Linux steve-ThinkPad-T410 3.8.0-30-generic#44-Ubuntu SMP 8月22日20:54:42 UTC 2013 i686 i686 i686 GNU / Linux <登记/> 2.测试期间的统计数据

      Right after Test App Starts Throwing Exception
      steve@steve-ThinkPad-T410:~$ free
                    total       used       free     shared    buffers     cached
       Mem:       3989340    3763292     226048          0       2548      79728
       -/+ buffers/cache:    3681016     308324
       Swap:      9760764    9432896     327868

      10 minutes after Test App Starts Throwing Exception
      steve@steve-ThinkPad-T410:~$ free
                    total       used       free     shared    buffers     cached
       Mem:       3989340    3770808     218532          0       3420      80632
       -/+ buffers/cache:    3686756     302584
       Swap:      9760764    9436168     324596


      20 minutes after Test App Starts Throwing Exception
      steve@steve-ThinkPad-T410:~$ free
                    total       used       free     shared    buffers     cached
       Mem:       3989340    3770960     218380          0       4376     104716
       -/+ buffers/cache:    3661868     327472
       Swap:      9760764    9535700     225064

      40 minutes after Test App Starts Throwing Exception
      steve@steve-ThinkPad-T410:~$ free
                    total       used       free     shared    buffers     cached
       Mem:       3989340    3739168     250172          0       2272     139108
       -/+ buffers/cache:    3597788     391552
       Swap:      9760764    9556292     204472

3 个答案:

答案 0 :(得分:2)

您的地址空间中可能没有1MB的连续内存页面。你有自由空间碎片。

答案 1 :(得分:2)

  

在我的测试期间,当有大约220M内存时,上面的代码开始抛出异常。从那一刻起,看起来应用程序无法再获得更多内存,因为TOP命令显示的空闲内存仍然高于210M。那为什么会发生这种情况呢?

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

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

您的程序会占用内存,在某些时候(当top显示200 Mb可用时)它会开始失败。

答案 2 :(得分:0)

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

grep “HIGHMEM” /boot/config-`uname -r`
grep “VMSPLIT” /boot/config-`uname -r`

了解内核的配置方式。

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

编辑:

因此,您的内核被配置为为每个用户空间进程提供地址空间3G,其中一些将用于程序,库和初始运行时内存(由于分叉将共享)。

因此你有4个孩子每人使用~3G~~12G + ~780M的其他程序。一旦孩子们开始报告错误,这将留下大约220M的免费。

您可以运行另一个子进程,或者可以使用AND64 / x86-64版本的Ubuntu重新安装,其中每个进程都可以分配更多内存。