按照标准,当调用std :: unordered_map的析构函数时(例如,当它离开创建它的作用域时),人们希望释放它分配的内存。但是我在多台计算机上运行的一个简单实验似乎与此冲突?考虑以下程序:
#include <chrono>
#include <iostream>
#include <map>
#include <unordered_map>
#include <memory>
#include <thread>
#include <vector>
void CreateMap() {
std::unordered_map<int, int> testMap;
for (int i=0; i < 10000000; i++) {
testMap[i] = 5;
}
std::cout << "finished building map" << std::endl;
std::this_thread::sleep_for (std::chrono::seconds(15));
std::cout << "about to exit from CreateMap()" << std::endl;
}
int main()
{
CreateMap();
CreateMap();
CreateMap();
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
在我的机器上,地图完成构建后会消耗10%的RAM,但是我们最后在CreateMap()中入睡。但是,退出RAM后仅下降到8%(一个人可以使用各种大小的地图来显示地图本身所占的比例超过2%),所以有人会认为CreateMap会泄漏内存吗?但是,对CreateMap()的3次调用或仅1次调用似乎没有什么不同(因此将内存回收到程序中,而不回收到RAM中?)。
这可能是我不了解的有关OS内存管理的奇怪事情,也就是说,程序有可能释放内存以供将来自己使用(将来的分配),而不能释放给OS(即,用于操作系统中的内存分配)。其他程序)?
请确保std::unordered_map
不会泄漏。您不能使用系统监视器来检查程序是否泄漏。如果有的话,您应该查看物理内存使用情况,而不是总内存或虚拟内存。因为页面可以交换到磁盘(页面文件),所以即使是物理内存也无法确定RAM的使用情况。即使这样,例如OS或c ++语言级别可能正在重用堆内存(as mentioned in comment)进行优化。涉及的因素太多,对于检测像泄漏的内存这样的微妙的东西有用的总价值太高了。一种寻找泄漏的简单方法(通常是有效的方法)是在程序终止时查看堆,例如。使用_CrtSetDbgFlag或类似工具。不用说,避免hand-rolled memory management并使用所有权语义对于避免代码泄漏有很长的路要走。