我有一台 WRT160NL linksys 路由器,内存为 32MB,安装了 OpwnWRT。我正在运行一个应用程序,它会将大量日志文件写入 USB 连接的闪存驱动器。(基本上每天 26MB,几乎与路由器的内存一样多)。
我亲眼目睹路由器每隔 24 小时左右就会重新启动一次。在监控路由器中的各种系统参数后,我注意到 /proc/meminfo 中的 Buffers 参数在一天内从 3kB 稳步下降到大约 700B,直到它重新启动。此外,在这 24 小时内,SUnreclaim 参数从 8k 稳步增加到 13k。重新启动后,这两个参数分别恢复到 3k 和 8k。
因此,我注意到,当 Buffers 参数达到 700B 阈值并且 SUnreclaim 达到 13k 阈值时,路由器都会重新启动。此时,平均负载开始稳步增加,直到达到必须重新启动的程度。我假设 Buffers 参数的减少与 SUnreclaim 参数的增加有关。
好的,我已经尝试清除缓存以释放内存(同步;echo 3 > /proc/sys/vm/drop_cache),但这并没有什么用,只是将问题延迟了一小段时间。我还尝试调整 /proc/sys/vm/ 中的一些与内存相关的变量,但收效甚微(无论我做什么,SUnreclaim 都会不断增加 - 而且我仍在尝试一些替代调整)。
问题是,当我在没有应用程序的情况下运行路由器时,所有这些参数在几天内都不会改变,并且路由器根本不会重新启动!
另外,当我关闭一些日志记录(通过 bash 脚本中的管道和重定向进行)时,下降幅度比平时要小(重新启动需要 4 天而不是 1 天)。
所以我认为问题与不可回收内存有关。解释“不可回收”这个名称,我假设这部分内存由内核保留,并且用户级别永远无法再次访问,这意味着在一个本来内存就很少的系统中,我几个小时内可用的内存越来越少……
关于不可回收 Slab 内存是什么以及它为什么会发生的信息似乎很少。如果您能解释一下,我将不胜感激。
有人能帮我了解问题可能出在哪里吗?或者我该如何阻止这些下降/增加的情况发生,从而导致路由器重新启动?
抱歉,我留下了遗嘱。提前致谢。
答案1
问题似乎与内核蓝牙驱动程序中的内存泄漏有关,每次发出蓝牙请求时都会有少量内存无法回收(我们每 4 秒发出一次,所以...),因此在 24 小时内几乎有一半的路由器内存对用户不可用。在对内核应用补丁并重新编译后,问题似乎已经消失。
因此,正如我所假设的那样,大量写入日志并不是问题所在,缓冲区数量的减少肯定是由于内核堵塞了内存,而不是因为内存将整个日志文件放入内存。毕竟,我并没有对 Linux 内存管理失去信心!
编辑:该问题似乎存在于 Backfire 的 Linux OpenWrt 2.6.32.25 内核(10.03,r24064)中。
以下是解决问题的方法:http://www.spinics.net/lists/linux-bluetooth/msg13995.html