我有一个类unordered_map
的字段。我在我的应用程序中创建了这个对象的单个实例,它包含在shared_ptr
中。该对象非常耗费内存,我想在使用它后立即将其删除。但是,重置指针只会释放对象占用的一小部分内存。如何强制程序释放对象占用的所有内存?
以下模拟程序重现了我的问题。 for循环打印垃圾只是为了给我足够的时间来观察top
使用的内存。析构函数在reset()
之后被调用。此外,紧接着,使用的内存从大约2 GB下降到1.5 GB。
#include <iostream>
#include <memory>
#include <unordered_map>
using namespace std;
struct A {
~A() {
cerr << "Destructor" << endl;
}
unordered_map<int, int> index;
};
int main() {
shared_ptr<A> a = make_shared<A>();
for (size_t i = 0; i < 50000000; ++i) {
a->index[2*i] = i + 3;
}
// Do some random work.
for (size_t i = 0; i < 3000000; ++i) {
cout << "First" << endl;
}
a.reset();
// More random work.
for (size_t i = 0; i < 3000000; ++i) {
cout << "Second" << endl;
}
}
编译器:g ++ 4.6.3。
答案 0 :(得分:5)
GCC的标准库没有“STL内存缓存”,默认配置(几乎每个人都使用)std::allocator
只调用new
和delete
,只调用malloc
}和free
。 malloc
实现(通常来自系统的C库)决定是否将内存返回给操作系统。除非您使用的是没有虚拟内存的嵌入式/受限制系统(或者您已经关闭了过度提交),否则您可能不想返回它 - 让库按照自己的意愿行事。
操作系统不需要内存,它可以为其他应用程序分配千兆字节的虚拟内存而不会出现问题。每当人们认为他们需要返回内存时,通常是因为他们不了解现代操作系统如何处理虚拟内存。
如果你真的想强制C库将内存返回给操作系统,那么C库可能会提供非标准的钩子,例如对于GNU libc,你可以调用malloc_trim(0)
来强制最顶层要返回到操作系统的大量可用内存,但这可能会使您的程序在下次需要分配更多内存时变慢,因为它必须从操作系统中恢复。有关详细信息,请参阅https://stackoverflow.com/a/10945602/981959(以及其他答案)。
答案 1 :(得分:4)
无法保证您的应用程序会将内存释放回操作系统。它仍可供您的应用程序使用,但在您的应用程序退出之前,操作系统可能无法回收它以供一般使用。