检测嵌入式Linux

时间:2018-01-29 15:46:16

标签: memory malloc embedded-linux swapfile

我的团队开发了一个在嵌入式Linux上运行的复杂的基于多进程C ++的系统。由于没有交换分区,逐渐增长的内存泄漏可能会导致严重的问题。 (为了这个讨论,我们假设系统中分配的所有内存都填充了非零数据。)

现在,正如(简洁地)here所回答的,当操作系统没有RAM且没有交换时,它会丢弃干净的页面。据我所知,唯一的"清洁"这种情况下的页面包含const数据和当前/最近执行的Linux环境代码,特别是我们的可执行文件和共享库,可以无害地丢弃,然后根据需要从文件系统重新加载。

首先,最近最少使用的页面将是第一个去的,所以这几乎没有被注意到,但随着越来越多的内存被分配并且摆动空间的数量减少,所需的代码更经常被换掉然后回来系统开始无声地和无形地捶打,但我们看到的唯一标志是系统变得越来越慢,反应越来越慢,直到最终内核的杀手进入并完成它的事情。

这种情况并不一定需要发生内存泄漏;它可能只是因为我们的软件的自然内存需求超过可用RAM。这样的情况更难以捕捉,因为系统不会崩溃,并且由于颠簸引起的性能损失并不总是立即引人注意,并且可能与其他不良性能的原因混淆(例如效率低下的算法)。 / p>

我正在寻找一种方法来在性能开始受到影响之前明确地捕捉并标记这个问题; 理想情况下,我希望监控发生的干净页面丢弃量,希望不需要特别重建的内核。然后我可以建立一个阈值,超过该阈值就会引发错误。当然,任何更好的想法也将受到赞赏。

我已尝试过其他解决方案,例如使用top监控进程内存使用情况,或让进程使用mallinfo(3)进行自我监控,但仍然无法捕获所有情况或清楚回答整体内存使用状态是什么的问题。我看过的另一件事是"免费" free输出中的列,但无论是否发生颠簸,都可以显示低值。

2 个答案:

答案 0 :(得分:1)

我认为您正在寻找的指标是页面错误。作为绝对值,它无法告诉您任何事情,因为页面错误是系统操作的正常部分,但作为相对值,也许它可能有用:如果您绘制程序在不同内存使用级别生成的页面错误量,我敢打赌,当你的程序超出可用内存的时候会有一个重大的跳跃,并启动这个干净的页面丢弃&加载行为。

答案 1 :(得分:1)

Alex的回答通过提及页面错误向我指出了正确的方向,但更具体的答案是主要页面错误。来自perf_event_open(2) man page

 PERF_COUNT_SW_PAGE_FAULTS_MAJ
     

这会计算主要页面错误的数量。这些需要处理的磁盘I / O.

因此,虽然这些不是我要求的干净页面丢弃,但它们是推论 - 它们表明以前换掉的东西会在中从磁盘交换回来。在无交换系统中,唯一可以从磁盘交换的是干净的页面。在我的测试中,我发现这些故障通常很少而且很远,但是当内存不足时突然出现峰值(在我的系统上,连续5秒以上每秒发生3次或更多次故障),以及该指示与系统变慢和响应速度一致。

至于实际查询此统计信息,这已在Measure page faults from a c program中得到解答,但我建议从perf_event_open(2)手册页底部的代码示例(请参阅上面的链接)开始进行此更改:

pe.type = PERF_TYPE_SOFTWARE;
pe.config = PERF_COUNT_SW_PAGE_FAULTS_MAJ;

假设您想要获得系统范围的统计信息而不仅仅是与当前流程相关,请将实际的开放行更改为:

fd = perf_event_open(&pe, -1, cpu, -1, 0);

这里的cpu参数很棘手。在单核单CPU系统上,只需将其设置为0.否则,您必须为每个核打开一个单独的性能计数器(具有单独的fd),全部读取并总结其结果。对于解释原因的线程,请参阅here。使用get_nprocs(3)获取核心数最容易。