提问人:Santiago 提问时间:7/27/2023 更新时间:7/27/2023 访问量:65
删除 std::unordered_map 不会将内存释放回操作系统 [duplicate]
Deleting std::unordered_map does not release memory back to the OS [duplicate]
问:
这个问题在这里已经有答案了:
调用 free 或 delete 是否会将内存释放回“系统” (8 个答案)
为什么 free() 函数不将内存返回给操作系统? (2 个答案)
在 c++ 程序中删除不会释放内存 [已关闭] (1 个答案)
4个月前关闭。
我有如下场景,在启动我的应用程序时,我订阅了一个中间件并下载了最新的状态(快照),我需要做一些过滤逻辑,然后处理快照。为此,我将初始快照放在 .在那之后,我不再需要地图,所以我希望它的内存被释放回操作系统。未序列化的快照记录占用大量内存,最高可达 15GB。因此,释放这种记忆非常重要。这是我拥有的代码。std::unordered_map
class Consumer
{
public:
Consumer(Processor& p)
: m_processor(p)
, m_snapshot(false)
, m_sub([this](const auto& msg) {
if (m_snapshot)
addToCache(msg);
else
m_processor.process(Order(msg));
},
[this](const auto& state) {
if (state == State::BEGIN)
m_snapshot = true;
else if (state == State::END)
m_snapshot = false;
playCache();
})
{
}
private:
void addToCache(const Input& input)
{
// if logic
m_cache[input.header.key()] = Order(input);
}
void playCache()
{
for (auto& [_, order] : m_cache)
m_processor(std::move(order));
m_cache.clear();
}
private:
Processor m_processor;
bool m_snapshot;
Sub m_sub;
std::unordered_map<std::string, Order> m_cache;
};
这显然不会将内存释放回操作系统(签入我的进程,它仍然使用相同数量的内存)。htop
“m_processor”“使用”消息,仅在字符串中存储序列化版本。Order
我很确定内存没有被释放,它来自这张地图,因为我做了以下测试:
- 无需进行任何过滤(根本不添加)并简单地处理所有消息(即使它们更多)可以显着降低 5GB 左右的内存消耗,而 15GB 的缓存进行过滤然后处理。
m_cache
- 我很确定上游没有内存泄漏。我尝试注释掉添加到地图和处理的部分。又名,仍然获取快照,但将其扔掉,我再次获得更少的内存使用量。
m_sub
我知道这并不意味着释放内存,因此正如其他帖子中建议的那样,我尝试了以下操作:.clear()
- 进行交换,即:
playCache
void playCache()
{
for (auto& [_, order] : m_cache)
m_processor(std::move(order));
m_cache.clear();
std::unordered_map<std::string, Order> empty;
std::swap(m_cache, empty);
}
相同的结果是,内存不会释放回操作系统。
- 完成后进行和调用重置:
m_cache
std::unique_ptr
void playCache()
{
for (auto& [_, order] : *m_cache)
m_processor(std::move(order));
m_cache->clear();
m_cache.reset();
}
结果还是一样。
我错过了什么吗?为什么内存没有释放回操作系统?
如果它有帮助,数据类型很简单:
struct Order {
Order() = default;
Order(const Input& i)
: header_(i.header())
, body_(deserializeProto(i.body())
{
}
protobuf::Header header_;
protobuf::Body body_;
};
提前致谢。
答: 暂无答案
评论
delete
不需要将内存返回到操作系统,并且很少这样做。获取内存并将其释放回操作系统是一项成本高昂的操作,因此程序可以保留内存,直到操作系统请求返回内存或程序结束。