整理RAM / OOM故障


11

这个问题相当冗长,因此我将在顶部询问问题,然后逐一探讨提出问题的方法:

  1. (基于Busybox的)rm是否没有执行,因为没有足够的连续RAM?
  2. 如果是这样,是否有一种轻巧的方法来对DMA进行碎片整理-无需重新启动系统?
  3. 如果不是,是什么原因造成的?我如何防止它将来发生?

在过去几天中我们的测试系统相当密集地运行之后,我通过telnet进入系统并检查了测试结果。当我删除一些数据时,系统返回了命令行(就像命令已正确执行一样)。当我检查目录是否有另一组结果时,我看到该文件仍然存在(使用ls)。

此后,我注意到越来越多的shell命令无法按预期执行。

rm无法正确执行后,我将从dmesg的输出开始:

从进程6821(rm)分配长度61440失败

DMA每个CPU:

CPU 0:嗨:0,btch:1 usd:0

Active_anon:0 active_file:1 inactive_anon:0 inactive_file:0无法清除:6脏:0回写:0不稳定:0空闲:821平板:353映射:0页表:0反弹:0

DMA空闲时间:3284kB分钟:360kB低点:448kB高位:540kB active_anon:0kB inactive_anon:0kB active_file:4kB inactive_file:0kB不可撤销:24kB当前:8128kB pages_scanned:0 all_unreclaimable?没有

lowmem_reserve []:0 0 0

DMA:31 * 4kB 47 * 8kB 42 * 16kB 64 * 32kB 1 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 0 * 4096kB = 3284kB

共14个页面缓存页面

无法为过程数据分配RAM,错误号12

最初,我以为我无法在连续内存的最大部分中运行该程序。意味着DMA过于分散,我将不得不找到一种使系统对内存进行碎片整理的方法。

然后,我进行了快速的数学/健全性检查,意识到该程序应该能够在唯一的64kB连续内存插槽中运行。Rm请求61440字节(60kB)。

我做了一个很好的旧的“手动碎片整理”,然后重新启动了系统。当我重新启动系统时,我输出/ proc / buddyinfo:

Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0

我怀疑映射到:

  • 2个4 kB
  • 8 x 8 KB
  • 3 x 16千字节
  • 12 x 32 kb
  • 1个128 kB
  • 1 x 512 kb

但是,如果将上述值列表加总,则它与/ proc / meminfo的输出不匹配:

MemTotal:           6580 kB
MemFree:            3164 kB
Buffers:               0 kB
Cached:              728 kB
SwapCached:            0 kB
Active:              176 kB
Inactive:            524 kB
Active(anon):          0 kB
Inactive(anon):        0 kB
Active(file):        176 kB
Inactive(file):      524 kB`
Unevictable:           0 kB
Mlocked:               0 kB
MmapCopy:            844 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:             0 kB
Mapped:                0 kB
Slab:               1268 kB
SReclaimable:        196 kB
SUnreclaim:         1072 kB
PageTables:            0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        3288 kB
Committed_AS:          0 kB
VmallocTotal:          0 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB

回顾一下,我的问题是:

  1. rm是否没有执行,因为没有足够的连续RAM?
  2. 如果是这样,是否有一种轻巧的方法来对DMA进行碎片整理-无需重新启动系统?
  3. 如果不是,是什么原因造成的?我如何防止它将来发生?

我正在使用运行uClinux版本2.6.30的Lantronix的XPort Pro(8MB,Linux OS)。使用中的外壳是安静的。


次要点:您从内存块列表中遗漏了1 x 2048 kB。如果包括这些,则总和为3192 kB,非常接近/ proc / meminfo中列出的3164 kB。
亚历克斯·塞尔比

Answers:


11

关于您的问题2(对内存进行碎片整理),引自https://www.kernel.org/doc/Documentation/sysctl/vm.txt

compact_memory

仅在设置CONFIG_COMPACTION时可用。当将1写入文件时,将压缩所有区域,以便在可能的情况下在连续的块中提供可用内存。例如,这在分配大页时可能很重要,尽管进程也会根据需要直接压缩内存。

这意味着以下命令(以root特权执行,并且如果启用了上述内核选项)

echo 1 > /proc/sys/vm/compact_memory

应该告诉内核尝试对内存进行尽可能的碎片整理。请注意,例如在某些RHEL6版本上,这可能会使内核崩溃。


1
感谢您抽出宝贵的时间回来对一个老问题发表评论!
OldTinfoil

7

这花了一些时间,但我认为我会一直等到对所有3个子问题都回答完为止。

不过,在开始之前,我会提到将“碎片整理”工作内存称为“紧凑”工作内存。

1. rm是否没有执行,因为没有足够的连续RAM?

我的结论是正确的-rm没有执行,因为连续的RAM不足。系统一直在获取RAM并将其碎片化,因此使其无法回收。

2.如果是这样,是否有一种轻巧的方法来对DMA进行碎片整理-无需重新启动系统?

事实证明,只有重新启动嵌入式系统,才能压缩内存。对于没有MMU的系统,预防是游戏的名称。

我一部分人在思考是否有可能入侵Linux内核以在软件中模拟MMU。我想如果可能的话,有人会做的。我无法想象它是一个全新的概念;)

3.如何防止将来发生这种情况?

对于这个项目,我每次都使用cron手动启动程序。更好的方法是在启动时调用程序,然后强制程序进入睡眠状态,直到需要它为止。这样,无需在每次使用时分配内存。从而减少碎片。

在项目的第一次迭代中,我们依靠我的shell脚本调用来执行关键功能(例如rm)。如果不需要,我们认为不需要重新发明轮子。

但是,对于没有MMU的系统,我建议尽可能避免使用Shell-

问题,如果执行,会发生什么ls -la /path/to/directory/ | grep file-i-seek?)

答案:它将启动一个新的子进程)

如果您需要在C程序中实现某些核心Shell脚本功能,建议您查看BusyBox中使用的源代码。您可能会在嵌入式系统中使用C。


感谢您抽出宝贵的时间回来分享您的发现。
Caleb 2012年

3
[我意识到这很旧]模拟MMU很难...没有MMU,每个程序都会直接使用出现在内存总线上的物理地址。您可以模拟一个,但必须拦截每个内存访问(就像实际的MMU一样)。性能会很糟糕。另外,您可以使用间接指针(如Mac OS Classic那样,将其称为“句柄”),但是您将拥有一个完全困难的API,并且在抢占时会遇到一个非常困难的问题(Mac OS Classic使用协作式多任务处理) 。
derobert

感谢您回来并花时间写回覆。不知道MacOS classic会这样做。
OldTinfoil 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.