Dan*_*ina 5 c++ memory memory-leaks memory-management
我已经看到使用map.clear()并且map.rehash(0)不会从我的 RAM 中释放预期的内存。
我用以下代码创建了一个程序:
int main() {
std::unordered_map<std::string, int> m1;
std::unordered_map<std::string, int> m2;
// fill the maps m1 and m2 with 5 million elements
// bucket_count = 5098259; size = 5000000
// now I clear m1
m1.clear();
m1.rehash(0);
// m1: bucket_count = 2; size = 0
// m2: bucket_count = 5098259; size = 5000000
// now I clear m2
m2.clear();
m2.rehash(1);
// m1: bucket_count = 2; size = 0
// m2: bucket_count = 2; size = 0
}
Run Code Online (Sandbox Code Playgroud)
根据程序的每一步bucket_count和size之后,似乎有很多空间从RAM中释放出来。但是,检查与系统监视器一起使用的 RAM,我得到以下演变
即使在清除并重新散列两个映射之后,内存也仅在程序完成时释放。实际上释放的内存很少,但我不确定这是否可以在图片中看到。这怎么可能?
我如何才能真正从 RAM 中释放该内存?
我正在使用动态编程算法来解决 Linux 中 4Gb RAM 的旅行商问题。由于内存不足而崩溃,因此我正在尝试优化程序使用的内存。
经过一些改进后,我保留了两个unordered_map:
迭代结束后,我交换它们,以便cost具有新的计算值,并清除new_costs 以 尝试释放内存并开始构建下一次迭代。
代码是这样的:
std::unordered_map<std::string, int> costs(5098259);
std::unordered_map<std::string, int> new_costs(5098259);
for (int m = 1; m <= n; m++) {
new_costs.clear();
new_costs.rehash(5098259);
while (something) {
// I build the content of new_costs based on the content of costs
}
std::swap(costs, new_costs);
}
Run Code Online (Sandbox Code Playgroud)
我最多必须分别在其中存储 2496144 和 2704156 个元素。这使得总共同时存储了5200300 个元素。鉴于密钥是一个最多包含 70 个字符的字符串 --71 个字节 -- 并且存储的值是一个浮点数 --4 个字节--,我将存储大约 380 Mb。
我知道这unordered_map不是内存有效的,但是程序完全使用了我的 RAM 和我的交换内存,所以我一定遗漏了一些东西。
我已经使用C ++为一个星期左右了,我不知道是不是内存管理std::map和std::unordered_map是相同的,或者如果它们之间存在着相关差异。
我也不知道解除分配是否与释放对象使用的内存完全相同,因此有更多可用的 RAM。
如果两者相同,我基本上是在问同样的问题。但是,无论如何,该问题的答案是解释内存保留背后的原因,而不是提供解决方案。
您需要担心三个级别的内存使用情况,并且您的进程内存占用可能向您显示了错误的级别。
正在使用的内存
容器中正在使用的东西。简单的。
每个容器分配器
您的容器有一个分配器。这可能决定分配比请求更大的块,并且还可能保留释放的内存以供以后重用。这两种方法通常都会以内存使用为代价来提高速度。
您可以使用交换技巧来释放此缓存:创建一个空的临时容器和std::swap它们。这也会移动分配器,这意味着当临时超出范围时,任何旧的缓存存储都将被释放。
无论如何,对于释放的某些值:内存可能会返回到您的...
进程范围的动态分配器(通常是“堆”)。
出于完全相同的原因,这可能会决定将内存缓存在您的进程中。它没有义务将该内存返回给系统(直到您的进程退出)。
强制程序将内存返回给系统的唯一方法是编写自己的分配器,使用适当的系统调用来显式执行此操作。
在具有虚拟内存的系统上,推断程序内存使用情况的明智方法是担心使用了多少内存,而不是过多担心其虚拟地址空间的大小。
注意。如果尽管您清除并重新使用容器,内存使用量仍持续增长,则可能存在泄漏或内存碎片。这确实是个问题。如果运行期间内存使用量没有减少,则完全正常,无需担心。
| 归档时间: |
|
| 查看次数: |
5916 次 |
| 最近记录: |