问题描述
我的项目有 RAM 限制,因为它包含大量数据操作。问题是,我注意到调用 std::set<std::pair<int64_t,int64_t>>::clear()
实际上并没有释放任何内存。重现问题的代码:
std::set<std::pair<int64_t,int64_t>> stltest;
for (size_t i=1; i<=250000; i++)
{
stltest.insert({i,i});
}
std::cout << " "; // place for a breakpoint
stltest.clear();
std::cout << " "; // place for a breakpoint
在 ubuntu 20.04 上,标准的 C++ 编译器这个东西需要 17.7 MB 并且它不会还给它。可能 clear()
只是将 size()
设置为零,但对内容没有任何作用,这很奇怪。是我笨还是我笨?能拿回记忆吗,我真的很需要。
编辑:尝试手动创建新的并删除之后仍然无法恢复记忆。
解决方法
可能 clear() 只是将 size() 设置为零,但对内容没有任何作用
没有。它会破坏元素并释放它们的内存。
我能找回记忆吗
当然,如果您实现自己的 malloc
并替换标准的。
实际上不,这不是一个有用的目标。
我真的需要它。
你认为你需要什么?你打算用它来创建更多的对象吗?因为这正是 malloc
的实现保留内存的目的。
您可以让 stltest
超出范围,或者
{
std::set<std::pair<int64_t,int64_t>> reclaim_memory;
stltest.swap(reclaim_memory);
}
在一个新的范围内(所以括号很重要)以便分配的内存
当 reclaim_memory
超出范围时被释放。
在 cppreference 上,并没有详细说明 clear()
期间发生的事情……对于向量,cppreference 声明容量保持不变,因此它会销毁但不会释放。并简要查看我的 clang 安装中的头文件,set 也只是在销毁对象,似乎没有发生释放。然而,这不是内存泄漏。
我相信这是使用的底层函数...
template <class _Tp,class _Compare,class _Allocator>
void
__tree<_Tp,_Compare,_Allocator>::clear() _NOEXCEPT
{
destroy(__root());
size() = 0;
__begin_node() = __end_node();
__end_node()->__left_ = nullptr;
}
由于集合没有 shrink_to_fit()
,所以最简单的选项是其他人提到的。让它超出范围。