【发布时间】:2014-12-10 17:44:38
【问题描述】:
这是我在 stackoverflow 上的第一个问题。我在很大程度上寻找了以下代码行所遇到的原因:
unsigned long long _mem1= getUsedVirtualMemory();
vector.erase(vector.begin() + _idx);
contained= false; // don't stop the loop
_idx--; // the removed object has redefined the idx to be consider.
_mem1 = getUsedVirtualMemory() - _mem1;
if (_mem1 > 0) printf("Memory - 2 mem1: %lu\n" , _mem1);
我的程序中有大量内存消耗,经过密集的调试会话、一些 printfs 和耗时的分析,我到达了这一点:
getUsedVirtualMemory 使用以下代码实现:
PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc));
SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
return virtualMemUsedByMe;
获取进程分配的虚拟内存量;向量是对象的向量(不是指针)。
在大多数情况下,向量的擦除方法似乎按预期工作,但在某些情况下,该向量的擦除方法似乎增加了进程使用的内存而不是释放它。我在代码周围的很多情况下都使用 Windows 系统函数 GetProcessMemoryInfo 来调试这个问题,它似乎返回了已用虚拟内存的实际值。
我正在使用 Visual Studio C++ 2010 Professional。
如果需要更多信息,请告诉我。
感谢您的任何回复。
更新:
你在回复中写的一切都是正确的,我忘记了以下细节:
- 我已经知道向量具有大小(元素的实际数量)和容量(分配的用于存储元素的插槽)
- 我已经知道擦除方法不会释放内存(我查找了很多关于该方法的文档)
- 最后,我稍后会在该向量中添加其他元素,因此我不需要缩小该向量。
实际的问题是,在这种情况下,最后一行代码中“_mem1”的值显示了1.600.000字节的差异:内存的不合理增加,而我预计是0字节。
此外,在操作后已用内存的值小于第一个的情况下,我希望在 Is unsigned integer subtraction defined behavior? 中解释的内容会有一个非常大的数字
我得到一个大于 0 但相对较短的值,而不是预期的结果。
为了更好地了解问题的发生率,在这段代码上迭代数千次,意外分配了大约 20 Gb 的虚拟内存。
【问题讨论】:
-
释放运行时库函数的分配并不一定会将任何东西释放回操作系统。内存分配器通常会保留一个可用块池来满足以后的分配,而不会浪费时间将内存交还给操作系统以便稍后重新请求它。因此,您没有看到内存使用量减少也就不足为奇了。
-
我绝对同意你的观点,但我无法证明“为什么擦除操作应该分配大约 1.5Mb 的额外内存?”
标签: c++ visual-studio-2010 memory vector erase