unordered_map:clear() 不会在 clear() 上释放堆
unordered_map: clear() does not release heap on clear()
我在 Solaris 10 上使用 g++ 4.9.2 使用 unordered_map,但令人惊讶的是我发现 clear() 不会释放堆。 下面是示例代码:
#include <iostream>
#include <unordered_map>
int main ()
{
std::unordered_map<long long, long long> mymap;
mymap.rehash(200000);
getchar();
for (int i = 0; i < 2000000; i++) {
mymap[i] = i*i;
}
std::cout << "current bucket_count: " << mymap.bucket_count() << std::endl;
std::cout << "current size: " << mymap.size() << std::endl;
getchar();
mymap.clear();
std::cout << "current bucket_count: " << mymap.bucket_count() << std::endl;
std::cout << "current size: " << mymap.size() << std::endl;
getchar();
return 0;
}
当 progranm 正在等待 getchar() 时,我正在观察程序的堆大小。而且,这是通过pmap -x <PID> | grep heap
找到的堆快照
1. While waiting on 1st getchar(): `0002C000 792 792 792 - rwx-- [ heap ]`
2. After 1st getchar(): it prints:
current bucket_count: 3439651
current size: 2000000
Heap shows while waiting on 2nd getchar():
0002C000 3920 3920 3920 - rwx-- [ heap ]
00400000 73728 72272 72272 - rwx-- [ heap ]
3. After 2nd getchar(): it prints:
current bucket_count: 3439651
current size: 0
Heap shows while waiting on 2nd getchar():
0002C000 3920 3920 3920 - rwx-- [ heap ]
00400000 73728 72272 72272 - rwx-- [ heap ]
这表明(步骤 3)clear() 对堆没有影响。虽然,文件说,
std::unordered_map::clear
void clear() noexcept;
Clear content
All the elements in the unordered_map container are dropped: their destructors are called, and they are removed from the container, leaving it with a size of 0.
但是,我的堆计数并不反映这一点。 有没有其他方法可以释放unordered_map对象占用的堆?或者,我应该使用其他东西吗? 请指导如何从unordered_map释放内存?
地图的内容将被擦除。与磁盘中的文件类似(仅从索引中删除)。如果下次可以使用它,释放内部存储器将是无效的。
如果你不能真正释放地图内存,你需要摧毁整个对象。或者您可以尝试用零调用void reserve( size_type count );
。(我没试过)
unordered_map:clear() 不会在 clear() 上释放堆
C++标准不需要clear
释放内存。
但是,我的堆计数并不反映这一点。
文档没有提到堆。调用了元素的析构函数,正如您所确认的,大小为 0。如果添加新元素,它们可能会重用先前清除的元素使用的内存。
有没有其他方法可以释放unordered_map对象占用的堆?
销毁地图肯定会释放其所有内存。
mymap.rehash(0)
也可能有效。
但是,仅仅因为内存被释放给实现(通过调用free
),并不意味着实现一定会向操作系统释放内存。实现可能会决定将内存重用到其他分配中(尽管这通常仅适用于较小的分配)。
在C++中没有标准的方法可以做到这一点,但 Linux 提供了一个函数malloc_trim
,它将尝试将释放的内存从堆的顶部释放到操作系统。
内存不会释放,因为映射应该继续使用,直到它超出范围或删除。对于此合理的默认用例,重新分配将导致不必要的开销。我的建议:
- 如果确实不再需要它,请将其范围限制在您需要它的位置,分别使用具有适当范围的地图的智能指针。
- 如果您仍然需要它,但暂时不需要,或者只有更少的元素,请使用空的临时地图(然后将删除)
swap
它。 - 显式调用析构函数并就地重新创建新映射。
- 释放错误后堆使用
- G锁定铸造到基础上会释放模拟行为
- 在将变量声明为引用时,堆在释放后使用
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 正在理解智能指针,但出现错误:未分配正在释放的指针
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- C++双重释放或损坏(out)
- 如何在c++中释放内存
- 使用全局声明的向量时,C++双重释放错误/损坏
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 调用析构函数以释放动态分配的内存
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- unordered_map:clear() 不会在 clear() 上释放堆
- c++创建新的LinkedList类:Clear()方法指针被释放未分配
- vector clear()似乎无法释放push_back中分配的内存
- 对shared_ptr的向量调用clear().内存会被释放吗
- STL vector.clear()导致内存双元释放或pthreads程序损坏
- unordered_map::clear() 是否释放 C++ 中元素占用的内存