std::bad_alloc异常,尽管有足够的可用内存
std::bad_alloc exception although there is enough free memory
我的代码运行在64位Linux(openSUSE 13.1 x86_64)下,编译器是gcc(SUSE Linux)4.8.1。在程序执行的某个时刻,我得到了一个std::bad_alloc异常,它源于std::vector push_back调用。如gdb:所示
(gdb) bt
#0 0x00007ffff6053849 in raise () from /lib64/libc.so.6
#1 0x00007ffff6054cd8 in abort () from /lib64/libc.so.6
#2 0x00007ffff694c655 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6
#3 0x00007ffff694a7c6 in ?? () from /usr/lib64/libstdc++.so.6
#4 0x00007ffff694a7f3 in std::terminate() () from /usr/lib64/libstdc++.so.6
#5 0x00007ffff694aa1e in __cxa_throw () from /usr/lib64/libstdc++.so.6
#6 0x00007ffff694af1d in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6
#7 0x0000000000457ca6 in allocate (__n=8388608, this=0x7ffffffe1f80)
at /usr/include/c++/4.8/ext/new_allocator.h:104
#8 _M_allocate (__n=8388608, this=0x7ffffffe1f80) at /usr/include/c++/4.8/bits/stl_vector.h:168
#9 std::vector<std::pair<long, long>, std::allocator<std::pair<long, long> > >::_M_insert_aux (
this=this@entry=0x7ffffffe1f80, __position=..., __x=...) at /usr/include/c++/4.8/bits/vector.tcc:345
#10 0x000000000045335c in push_back (__x=..., this=0x7ffffffe1f80) at /usr/include/c++/4.8/bits/stl_vector.h:913
#11 c_RoutingNetzwerk::LoescheAktuelleKnoten (this=this@entry=0x7ffffffe2f30,
aktuelle_knoten=std::vector of length 12803276, capacity 16777216 = {...}, ebene=ebene@entry=0,
aktueller_kantengrad=std::vector of length 17266677, capacity 17266677 = {...}, algo=...,
neue_abgehende_kanten=std::vector of length 4194304, capacity 4194304 = {...},
neue_eingehende_kanten=std::vector of length 4194304, capacity 4194304 = {...})
at RoutingAlgorithmus/RoutingNetzwerk.cpp:3275
对neue_abgehende_kanten.push_back(…)的调用使向量的大小加倍,所以我试图分配4194304*2*16字节=128 MB,但失败了。
另一方面,我有足够的内存(总共132GB),并且有足够的空闲内存(当我的程序在调试器中中断时拍摄的快照):
m2883:~ # free -m
total used free shared buffers cached
Mem: 129151 128582 568 0 59 56334
-/+ buffers/cache: 72189 56962
Swap: 8195 5 8190
你知道为什么分配失败了吗?在我看来,系统似乎没有释放缓存供我的程序使用?!
我只是尝试了一个小实验,想出了
#include <cstdlib>
#include <stdio.h>
int main( int argc, char** argv)
{
void* p = calloc( 1, 256 * 1024 * 1024 );
if ( !p )
printf( "failedn" );
else
printf( "all donen" );
}
这对于128兆字节仍然有效,但对于256兆字节则失败。
和:
m2883:~ # free -mh
total used free shared buffers cached
Mem: 126G 125G 593M 0B 60M 54G
-/+ buffers/cache: 70G 55G
Swap: 8.0G 5.4M 8.0G
transit@m2883:~/test> ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 1033140
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1033140
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
服务器似乎在某种程度上配置错误。即使在一个只运行几个系统服务的新启动系统上,我也不能分配超过70 GB的空间,我将其读取为64 GB+8 GB的交换空间。我已经联系了服务器管理员,并对这种情况进行了投诉。
如果没有关于代码和系统配置的信息,很难确定。
记忆碎片可以解释这种症状。向量使用的内存是连续的,即使可用的总内存足够,如果没有所需大小的单个连续块可供分配,分配也会失败。
重复的分配、解除分配和重新分配很容易导致内存碎片。
超过一定的配额也可以解释这种行为。
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 类型总是使用其大小存储在内存中吗
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存