为啥我的 C++ 程序的内存使用量不断增长?
Posted
技术标签:
【中文标题】为啥我的 C++ 程序的内存使用量不断增长?【英文标题】:Why does my C++ program's memory usage keep growing?为什么我的 C++ 程序的内存使用量不断增长? 【发布时间】:2012-04-27 01:52:18 【问题描述】:我是 Linux 和 C++ 新手,对我的应用程序的内存使用有疑问。
我的应用程序处理大量实时数据,大约每秒 500 条消息。
我使用 std::map 来管理(即插入和删除)所有消息。例如,
std::map<int, data_struct> m_map;
// when receive a new message, convert the message into a data structure
m_map.insert(std::pair<int, data_struct>(message.id, data));
// when need to erase a message
iter = m_map.find(id);
if (iter != m_map.end())
m.map.erase(iter);
m_map 的大小大致在2500左右,即应用一开始接收到很多新消息,然后逐渐需要擦除消息。大约 10 秒后,收到的新消息数量与需要删除的消息数量大致相同。
我的问题是,大约 20 分钟后,在 Linux System Monitor 中,我注意到我的应用程序使用的内存约为 1GB。而且它的大小似乎每 20 分钟翻一番。这是正常的吗,应用程序真的使用了那么多内存吗?我在这里遗漏了什么吗?
谢谢。
【问题讨论】:
您可能有内存泄漏。要么就是你的应用程序没有跟上你想象的那么好。大多数人可能会为这样的事情使用消息队列(例如RabbitMQ)。 也许你这样做有一些特定的原因,但你可以使用map.erase(id)
。有一个版本的erase,它将键作为参数并返回删除的元素数。
data_struct 是什么样子的?
将众多“make_unique”函数之一复制到您的代码中,并使用智能指针。很有可能,这将解决您的问题,以及您从未知道的许多其他问题。
【参考方案1】:
如果您的程序经常分配和取消分配内存块,您会得到fragemtation - 操作系统只能做很多事情来确保您分配的内存块之间没有间隙。但一般情况下,由此产生的内存使用会趋于平稳。
如果您的程序的内存不断增加,则您有内存泄漏 - 或者您忘记了 delete
对象(或者在 C 样式分配的情况下调用 free()
)或者您正在将您的对象堆积在一个容器中而忘记删除它们。
要查找丢失的delete
呼叫,请使用valgrind!
使用 valgrind 检测内存泄漏就像使用您喜欢的包管理器安装它然后运行一样简单
valgrind my_program
您的程序将运行,完成后,valgrind 将转储非常详细的内存泄漏报告及其来源,包括完整的堆栈跟踪。
valgrind 很棒。
【讨论】:
@michael,感谢您的建议。您能否提供一个链接或示例,说明如何使用 valgrind 查找丢失的删除调用、内存泄漏等。谢谢。【参考方案2】:map::erase() 调用对象的析构函数,所以你应该在那里处理内存泄漏
也许,如果您可以测量使用的内存增加了多少,以及数据结构的大小,您就会很好地提示问题出在哪里。
您每 20 分钟收到大约 600.000 条消息。如果内存使用量从 1GB 翻倍到 2GB,则每条消息会丢失 1.8kB(1GB / 20 分钟内 600.000 条消息)
【讨论】:
【参考方案3】:嗯,内存使用量增加不仅仅意味着泄漏。
RSS(驻留大小)是否在增加? 或者 VSZ(虚拟大小)是否增加?
你可以通过运行“ps -aux”找到
我的经验是,如果 RSS 保持不变并且 VSZ 不断增加,那么它肯定是内存泄漏。
如果 RSS 不断增长并且您的 VSZ 在某个时候稳定下来,那么您每次都会触及大量内存并且您正在增加所触及的内存量,在您的代码中发现这一点很困难。
【讨论】:
以上是关于为啥我的 C++ 程序的内存使用量不断增长?的主要内容,如果未能解决你的问题,请参考以下文章