即使仍有足够的内存,内存分配也会失败
Memory allocation failed even when there is still enough memory
我正在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 周四 8月 22 日 20:54:42 UTC 2013 i686 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
可能是您的地址空间中不再有 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 的地址空间,其中一些将与程序、库和初始运行时内存(由于分叉而共享)一起占用。
因此,您有 4 个孩子每人使用 ~3G - ~12G + ~780M 的其他程序。一旦孩子们开始报告错误,就剩下大约 220M 可用空间。
您可以只运行另一个子进程,也可以重新安装 AND64/x86-64 版本的 Ubuntu,其中每个进程将能够分配更多内存。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配