C++11 C++;vector在特定情况下的行为类似于泄漏内存

C++11 C++;vector在特定情况下的行为类似于泄漏内存,c++11,vector,memory-leaks,C++11,Vector,Memory Leaks,我发现了一种情况,在这种情况下,向量的行为就像泄漏内存,可以将其归结为一个最小的工作示例。在这个例子中,我(在一个函数中)创建了一个包含三个char向量的向量。首先,这些字符向量被推到大量元素上,它们的容量被缩小到它们的大小。然后在大向量上分配一个元素大小的向量。现在的问题是,使用的内存太大,即使函数返回并且向量被破坏,内存也不会被释放。我怎样才能找回记忆?为什么它会显示这种行为?如何避免这种泄漏行为 下面是示例代码(长度很抱歉): 但是,valgrind没有发现内存泄漏 我猜示例中的参数依赖于

我发现了一种情况,在这种情况下,向量的行为就像泄漏内存,可以将其归结为一个最小的工作示例。在这个例子中,我(在一个函数中)创建了一个包含三个char向量的向量。首先,这些字符向量被推到大量元素上,它们的容量被缩小到它们的大小。然后在大向量上分配一个元素大小的向量。现在的问题是,使用的内存太大,即使函数返回并且向量被破坏,内存也不会被释放。我怎样才能找回记忆?为什么它会显示这种行为?如何避免这种泄漏行为

下面是示例代码(长度很抱歉):

但是,valgrind没有发现内存泄漏

我猜示例中的参数依赖于系统来显示奇怪的行为。我使用带有g++4.8.2和x86_64内核的Linux Mint Debian版本。我编译时使用:

g++ -std=c++11 -O0 -Wall memory.cpp -o memory
也尝试了-O3,没有明确的优化设置

一些有趣的观点是:

  • 当我替换
    v=vector{1}通过
    v.clear();v、 收缩到合适的位置();v、 推回(1)问题保持不变。用
    v=vector(16777215)替换大向量的推和收缩“解决”内存问题
  • 16777215=2^24-1,所以它可能与内存边界有关
  • 此外,从程序在main开始时使用的内存(12516 kiB)加上大向量的内存,我们可以预期程序总共应该使用大约3*16777216 B+12516 kiB=61668 kiB,这大约是它最后使用的内存

在实际应用中,我使用向量收集应应用于FEM模拟刚度矩阵的操作。因为我想在可用内存的情况下达到可能的极限(同样在速度方面),所以我需要保存未缠绕的内存以避免交换。因为交换发生了,所以我假设VMSIZE值是可靠的。

< P>问题是,你误解了C++上下文中释放内存的含义。当应用程序释放内存时(使用<代码> SurrytoToFoe或删除对象或其他任何东西),它实际上只是将内存释放到C++运行时,而不必将其释放回系统,以便其他进程使用。C++运行时可以选择保留内存以便在相同的进程中重用。 通常,当内存被分割时会发生这种情况——空闲内存(在程序的VM空间中)被正在使用的内存包围。只有当空闲内存在程序内存空间的末尾时,C++运行时才选择(或能够)返回到系统。
通常,这种内存保留不是问题,因为当应用程序请求更多内存时,通常可以重用它。您可能遇到的问题是,因为C++运行时不能在使用内存块中移动,所以可能无法重用太小的空闲块。运行时可能会使用各种各样的技巧和启发式方法来避免这种情况,但它们并不总是有效。

请注意,您没有直接处理操作系统的内存分配例程。通常中间有另一个内存管理器替你做这项工作。
操作系统必须处理来自机器中运行的所有进程的请求,因此多次请求少量内存不是一个好主意。最好少问几次大块。应用程序中运行的内存管理器将保留一些内存块,希望应用程序以后需要它们

谢谢你给我指明了正确的方向!这就解释了所有的影响。我听说了,但这个问题从来没有发生过。所以我猜这就是他们所说的经验…;-)我现在可以深入研究现实世界的问题了。再次感谢。顺便问一下:我是否应该在标题中将“内存”替换为“系统内存”,以给出度量的提示?
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
g++ -std=c++11 -O0 -Wall memory.cpp -o memory