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

Memory 在嵌入式Linux中检测内存不足情况 我的团队开发了一个基于嵌入式Linux的复杂的多进程C++系统。由于没有交换分区,逐渐增长的内存泄漏可能会导致重大问题。(为了便于讨论,我们假设系统中分配的所有内存都充满了非零数据。),memory,malloc,embedded-linux,swapfile,Memory,Malloc,Embedded Linux,Swapfile,现在,正如所回答的(简洁),当操作系统内存不足且没有交换时,它会丢弃干净的页面。据我所知,在这种情况下,唯一“干净”的页面是那些包含常量数据和当前/最近从Linux环境执行代码的页面,特别是我们的可执行文件和共享库,它们可能会被无害地丢弃,然后根据需要从文件系统重新加载 首先,最近使用最少的页面将是第一个被使用的页面,因此这几乎不会被注意到,但是随着分配的内存越来越多,摇摆空间的数量减少,需要更多的代码会被交换出去然后再返回。系统开始悄无声息地、无形地抖动,但我们看到的唯一迹象是系统变得越来越慢

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

首先,最近使用最少的页面将是第一个被使用的页面,因此这几乎不会被注意到,但是随着分配的内存越来越多,摇摆空间的数量减少,需要更多的代码会被交换出去然后再返回。系统开始悄无声息地、无形地抖动,但我们看到的唯一迹象是系统变得越来越慢,响应速度越来越慢,直到内核的oom杀手介入并完成它的任务

这种情况不一定需要发生内存泄漏;这可能仅仅是因为我们软件的自然内存需求超过了可用RAM。这种情况更难发现,因为系统不会崩溃,而且颠簸造成的性能损失并不总是显而易见的,并且可能会与性能差的其他原因(例如低效的算法)混淆

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


我尝试过其他解决方案,如使用
top
监控进程内存使用情况,或使用
mallinfo(3)
让进程自行监控,但这仍然不能涵盖所有情况,也不能清楚地回答总体内存使用状态是什么的问题。另一件事我已经看过了,
free
的输出中的“free”列,但无论是否发生翻滚,它都会显示一个较低的值。

我认为您要寻找的度量标准是页面错误。作为一个绝对值,它不能告诉您任何事情,因为页面错误是系统操作的正常部分,但作为一个相对值,它可能会很有用:如果您将程序在不同内存使用级别生成的页面错误量绘制成图,我敢打赌,当您的程序超出可用RAM并开始此干净页面丢弃和加载行为时,将会有一个显著的跳跃。

Alex的回答提到页面错误,为我指明了正确的方向,但更具体的回答是主要页面错误。从:

这将统计主要页面错误的数量。这些需要磁盘I/O来处理

所以,虽然这些并不是我要求的干净页面丢弃,但它们是它们的必然结果——它们表示以前交换出去的内容何时从磁盘重新交换回来。在无交换系统中,唯一可以从磁盘交换的是干净的页面。在我的测试中,我发现这些故障通常很少,但在内存不足时会突然出现峰值(在我的系统上,在连续5秒以上的时间内,大约每秒发生3次或更多故障),并且这一指示与系统变得更慢、响应更差是一致的

至于实际查询此统计数据,这在中得到了回答,但我建议从
perf\u event\u 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),读取它们并总结它们的结果。有关解释原因的线索,请参见。使用它最容易获得内核数。

你真的不能,不管怎样,作为用户模式应用程序都不行。事实上,这比他描述的还要糟糕,当你试图分配内存时,Linux甚至没有告诉你没有内存。它会从
malloc
返回一个非空指针,尽管它没有足够的内存来备份它,并且只会在您使用返回给您的内存时抛出异常。@对于默认配置,这是正确的,但是内核可以简单地配置为不过度使用内存。@itaych为什么您认为free的输出是错误的?你能详细解释一下吗?@Blindy-我不是想让用户级API访问kswapd的内部或负责此分页的任何模块。我想从某个文件中读取此统计数据,例如/proc/vmstat或类似文件。在数十个或数百个可读的虚拟文本文件中可能有数千个统计值,其中肯定有一个包含我正在寻找的内容?@FrankMeerkötter-以下是我的实验结果:假设我使用的是1GB系统,使用的是980GB,“free”表示20MB空闲。然后,如果我再分配并填充100 MB,系统将(显然)丢弃100 MB干净的页面,“空闲”仍然会说20 MB空闲。这并不是完全错误——只是误导和遗漏了关键信息(即刚刚调出100 MB以保持内存可用!)。在oom杀手杀死内存不足的进程之前,我可以重复这个过程5到6次,在那之前,“free”将继续快乐而无用地报告20MB的空闲。实际
fd = perf_event_open(&pe, -1, cpu, -1, 0);