我发现了一种情况,其中向量的行为类似于泄漏内存,并且可以将其归结为最小的工作示例.在这个例子中,我(在一个函数中)生成一个包含三个char向量的向量.首先,这些char矢量被推入大量元素,它们的容量缩小到它们的大小.然后在大矢量上分配单元素大小的矢量.现在的问题是,使用的内存太大,即使函数返回并且向量被破坏,内存也不会被释放.我如何获得回忆?为什么它显示这个bahaviour?我该怎么做才能避免这种泄漏行为?
这里是示例代码(抱歉长度):
#include#include #include #include using namespace std; // see http://man7.org/linux/man-pages/man5/proc.5.html at /proc/[pid]/status string meminfo() { // memory information is in lines 11 - 20 of /proc/self/status ifstream stat_stream("/proc/self/status",ios_base::in); // get VmSize from line 12 string s; for ( int linenum = 0; linenum < 12; ++linenum ) getline(stat_stream,s); stat_stream.close(); return s; } void f() { vector > mem(3); // with 1,2 memory is fine size_t size = 16777215; // with 16777216 or greater memory is fine for ( vector & v : mem ) { for ( unsigned int i = 0; i < size; ++i ) v.push_back(i); v.shrink_to_fit(); // without this call memory is fine } cout << "Allocated vectors with capacities "; for ( vector & v : mem ) cout << v.capacity() << ", "; cout << endl << "used memory is now: " << meminfo() << endl; for ( vector & v : mem ) { v = vector {1}; if ( v.size() != v.capacity() ) cout << "Capacity larger than size." << endl; } cout << "Shrinked vectors down to capacity 1." << endl << "Used memory is now: " << meminfo() << endl; } int main() { cout << "At beginning of main: " << meminfo() << endl; f(); cout << "At end of main: " << meminfo() << endl; return 0; }
我机器上的输出:
At beginning of main: VmSize: 12516 kB Allocated vectors with capacities 16777215, 16777215, 16777215, used memory is now: VmSize: 78060 kB Shrinked vectors down to capacity 1. Used memory is now: VmSize: 61672 kB At end of main: VmSize: 61672 kB
但是,valgrind看不到内存泄漏.
我想这个例子中的参数是系统相关的,以显示奇怪的行为.我使用Linux Mint Debian Edition和g ++ 4.8.2以及x86_64内核.我编译:
g++ -std=c++11 -O0 -Wall memory.cpp -o memory
并尝试-O3并没有明确的优化设置.
一些有趣的观点是:
当我更换v = vector
的v.clear(); v.shrink_to_fit(); v.push_back(1);
问题保持不变.通过v = vector
"解决"内存问题来替换大矢量的推动和收缩.
16777215 = 2 ^ 24 - 1,所以也许它必须对内存边界做一些事情.
此外,人们可以期望程序在main(12516 kiB)的开头使用的存储器加上大矢量的存储器,程序应该总共使用大约3*16777216 B + 12516 kiB = 61668 kiB,这大约是它最终使用的内存.
在现实世界的应用程序中,我使用向量来收集应该应用于FEM模拟的刚度矩阵的操作.由于我想达到可用内存的可能性(也就速度而言),我需要保存不同的内存以避免交换.由于交换确实发生,我认为VmSize值是可靠的.