You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArmV8嵌入式系统memtester大内存mlock首次失败原因及解决办法

问题描述

我在无交换内存的ArmV8嵌入式系统上运行BusyBox,系统启动后执行free命令,输出如下:

/ # free
              total        used        free      shared  buff/cache   available
Mem:        1009476       18396      989128           0        1952      957260

随后运行申请690M内存的memtester(实际调用mlock),触发OOM-killer失败,日志如下:

pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 690MB (723517440 bytes)
got  690MB (723517440 bytes), trying mlock ...[  106.591843] memtester invoked oom-killer: gfp_mask=0x14040c0(GFP_KERNEL|__GFP_COMP), nodemask=(null),  order=0, oom_score_adj=0
[  106.603174] memtester cpuset=/ mems_allowed=0
[  106.607474] CPU: 1 PID: 1392 Comm: memtester Tainted: G           O    4.14.76-19.0.0 #1
[  106.620744] Call trace:
[  106.623161] [<ffff0000080892a8>] dump_backtrace+0x0/0x358
[  106.628475] [<ffff000008089614>] show_stack+0x14/0x20
[  106.633448] [<ffff000008b35a10>] dump_stack+0x90/0xb0
[  106.638421] [<ffff000008192e14>] dump_header+0x90/0x1e8
[  106.643562] [<ffff000008191f90>] oom_kill_process+0xd0/0x518
[  106.649130] [<ffff000008192a00>] out_of_memory+0x180/0x490
[  106.654529] [<ffff000008197ff4>] __alloc_pages_nodemask+0xadc/0xb60
[  106.660700] [<ffff0000081e6fd8>] alloc_pages_current+0x80/0xf0
[  106.666440] [<ffff0000081efb0c>] new_slab+0x40c/0x4e8
[  106.671410] [<ffff0000081f1a9c>] ___slab_alloc+0x474/0x548
[  106.676809] [<ffff0000081f1b94>] __slab_alloc.isra.22+0x24/0x38
[  106.682634] [<ffff0000081f2318>] kmem_cache_alloc+0x188/0x1c0
[  106.688291] [<ffff000008305614>] nfs_readhdr_alloc+0x1c/0x30
[  106.693861] [<ffff000008304400>] nfs_generic_pg_pgios+0x20/0xc0
[  106.699685] [<ffff000008303db4>] nfs_pageio_doio+0x34/0x80
[  106.705083] [<ffff000008304770>] __nfs_pageio_add_request+0xb0/0x370
[  106.711335] [<ffff0000083050c4>] nfs_pageio_add_request+0x14c/0x330
[  106.717502] [<ffff00000830595c>] readpage_async_filler+0x1c4/0x210
[  106.723585] [<ffff00000819d5c4>] read_cache_pages+0xb4/0x1a0
[  106.729153] [<ffff000008306394>] nfs_readpages+0xcc/0x1c0
[  106.734466] [<ffff00000819d80c>] __do_page_cache_readahead+0x15c/0x230
[  106.740892] [<ffff00000818fd58>] filemap_fault+0x308/0x5a0
[  106.746292] [<ffff0000081bf2f0>] __do_fault+0x20/0x70
[  106.751263] [<ffff0000081c4970>] __handle_mm_fault+0xa78/0x1010
[  106.757089] [<ffff0000081c5038>] handle_mm_fault+0x130/0x1d0
[  106.762660] [<ffff0000080a0c6c>] do_page_fault+0x134/0x3e8
[  106.768058] [<ffff0000080a0f68>] do_translation_fault+0x48/0x50
[  106.773883] [<ffff000008080ae4>] do_mem_abort+0x3c/0x98
[  106.779024] [<ffff000008080bd4>] do_el0_ia_bp_hardening+0x44/0xa0

之后我运行某应用并将其杀死,再次执行free命令结果与之前一致,但此时运行申请1G内存的memtester成功锁定了934MB:

/ # memtester 1G 1
memtester version 4.3.0 (64-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffffffffffff000
want 1024MB (1073741824 bytes)
got  934MB (979906560 bytes), trying mlock ...locked.

请问为何首次运行690MB的memtester会失败?如何无需运行应用就能让其成功?


问题分析与解决

首次运行失败的原因

从OOM日志的调用栈能看出,触发OOM的是NFS相关的内核内存分配请求,而非memtester的mlock直接导致:

  1. 系统刚启动时,内核slab分配器(管理内核对象内存)处于初始状态,可用的slab缓存不足。当memtester申请内存并执行mlock时,内核需要分配页表、slab对象等内核态内存,此时NFS模块刚好也在尝试分配内存(从nfs_readhdr_alloc等调用可验证),两者竞争内存资源,触发了OOM-killer。
  2. 首次运行时内存碎片化更严重,内核无法凑出连续内存块满足内核态内存需求;而运行并杀死应用后,内存被重新整理,碎片化程度降低,同时slab缓存被预热,有了足够可用的内核内存,因此memtester能成功锁定更多内存。

另外注意:free命令的available是用户态可用内存的估算值,不包含内核预留内存,所以即使显示有957MB可用,内核态内存不足时依然会触发OOM。

无需运行应用的解决方法

  • 预热内核slab缓存:手动触发内核内存分配操作,比如执行find / -type f | head -1000(遍历大量文件,让文件系统模块分配slab对象),或者dd if=/dev/zero of=/tmp/test bs=1M count=100 && rm /tmp/test,通过读写操作让内核提前分配好所需的slab缓存。
  • 调整内核内存预留参数:如果允许修改内核参数,可适当降低vm.min_free_kbytes(内核预留的最小空闲内存),命令为echo 4096 > /proc/sys/vm/min_free_kbytes(数值需根据实际情况调整,注意此操作可能影响系统稳定性)。
  • 禁用NFS相关模块:如果系统不需要NFS,可在启动时禁用NFS客户端/服务端模块,避免NFS后台触发内存分配请求,减少竞争。
  • 整理内存碎片:执行echo 3 > /proc/sys/vm/drop_caches清理缓存,若内核支持,再执行echo 1 > /proc/sys/vm/compact_memory主动压缩内存,降低碎片化程度。

内容的提问来源于stack exchange,提问作者Johnnie Walker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:45:05