4

我正在使用 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. 软件和硬件信息
RAM 为4G,交换空间约为9G字节。运行“uname -a”给出: Linux steve-ThinkPad-T410 3.8.0-30-generic #44-Ubuntu SMP Thu Aug 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
4

3 回答 3

2

可能是您的地址空间中没有更多的 1MB 连续内存页。你有可用空间碎片。

于 2013-09-20T16:22:09.017 回答
2

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

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

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

发生的事情是你的程序吃掉了内存,并且在某个时刻(当 top 显示 200 Mb 空闲时)它开始失败。

于 2013-09-20T16:22:15.877 回答
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 重新安装,每个进程将能够分配更多的内存。

于 2013-09-24T06:42:01.540 回答