我的团队开发了一个在嵌入式 Linux 上运行的基于 C++ 的复杂多进程系统。由于没有交换分区,逐渐增长的内存泄漏可能会造成很大的麻烦。(为了便于讨论,我们假设系统中分配的所有内存都填充了非零数据。)
现在,正如这里(简洁地)回答的那样,当操作系统用完 RAM 并且没有交换时,它会丢弃干净的页面。据我了解,在这种情况下唯一的“干净”页面是那些包含 const 数据和当前/最近从 Linux 环境执行的代码,特别是我们的可执行文件和共享库,它们可能会被无害地丢弃,然后根据需要从文件系统重新加载.
起初,最近最少使用的页面会最先被删除,因此几乎不会注意到这一点,但随着分配的内存越来越多,回旋余地的数量减少,需要的代码更频繁地被换出然后再重新进入。系统开始无声无息地颠簸,但我们看到的唯一迹象是系统变得更慢且响应更慢,直到最终内核的 oom-killer 介入并完成它的事情。
这种情况不一定需要发生内存泄漏;这可能只是因为我们软件的自然内存需求超过了可用 RAM。这种情况更难捕捉,因为系统不会崩溃,并且由抖动引起的性能损失并不总是立即引起注意,并且可能与导致性能不佳的其他原因(例如效率低下的算法)相混淆。
我正在寻找一种在性能开始受到影响之前明确地捕捉和标记这个问题的方法;理想情况下,我想监视发生的干净页面丢弃的数量,希望不需要专门重建的内核。然后我可以建立一些阈值,超过这个阈值就会引发错误。当然,任何更好的想法也会受到赞赏。
我尝试了其他解决方案,例如使用 监控进程内存使用情况top
,或者使用 让进程自我监管,mallinfo(3)
但这仍然不能捕捉所有情况或清楚地回答总体内存使用状态的问题。我看过的另一件事是输出中的“免费”列,free
但无论是否发生颠簸,它都会显示一个低值。