我正在使用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
答案 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重新安装,其中每个进程都可以分配更多内存。