我正在研究嵌入式Linux目标(32位ARM),一旦启动内核和核心软件,就需要确定有多少RAM可用于应用程序。 free和/ proc / meminfo报告的可用内存似乎与测试显示的应用程序实际可用的内存不一致。有没有一种方法可以正确地计算出真正可用的RAM数量,而无需在每个系统上运行,例如,施加压力?
我在下面的测试中使用的目标系统具有256 MB的RAM,并且不使用swap(未设置CONFIG_SWAP)。我在下面的测试中使用了3.14.79-rt85内核,但也尝试了4.9.39,并看到了相似的结果。在引导过程中,报告以下内容:
Memory: 183172K/262144K available (5901K kernel code, 377K rwdata, 1876K rodata, 909K init, 453K bss, 78972K reserved)
一旦系统初始化完成并且基本软件正在运行(例如dhcp客户端,ssh服务器等),我将得到以下报告的值:
[root@host ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 210016 320 7880 0 0 0 0 186 568 0 2 97 0 0
[root@host ~]# free -k
total used free shared buff/cache available
Mem: 249616 31484 209828 68 8304 172996
Swap: 0 0 0
[root@host ~]# cat /proc/meminfo
MemTotal: 249616 kB
MemFree: 209020 kB
MemAvailable: 172568 kB
Buffers: 712 kB
Cached: 4112 kB
SwapCached: 0 kB
Active: 4684 kB
Inactive: 2252 kB
Active(anon): 2120 kB
Inactive(anon): 68 kB
Active(file): 2564 kB
Inactive(file): 2184 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 2120 kB
Mapped: 3256 kB
Shmem: 68 kB
Slab: 13236 kB
SReclaimable: 4260 kB
SUnreclaim: 8976 kB
KernelStack: 864 kB
PageTables: 296 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 124808 kB
Committed_AS: 47944 kB
VmallocTotal: 1810432 kB
VmallocUsed: 3668 kB
VmallocChunk: 1803712 kB
[root@host ~]# sysctl -a | grep '^vm'
vm.admin_reserve_kbytes = 7119
vm.block_dump = 0
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 20
vm.dirty_writeback_centisecs = 500
vm.drop_caches = 3
vm.extfrag_threshold = 500
vm.laptop_mode = 0
vm.legacy_va_layout = 0
vm.lowmem_reserve_ratio = 32
vm.max_map_count = 65530
vm.min_free_kbytes = 32768
vm.mmap_min_addr = 4096
vm.nr_pdflush_threads = 0
vm.oom_dump_tasks = 1
vm.oom_kill_allocating_task = 0
vm.overcommit_kbytes = 0
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.panic_on_oom = 0
vm.percpu_pagelist_fraction = 0
vm.scan_unevictable_pages = 0
vm.stat_interval = 1
vm.swappiness = 60
vm.user_reserve_kbytes = 7119
vm.vfs_cache_pressure = 100
根据上述数字,我希望将来有约160 MiB可用。通过调整sysctl vm.min_free_kbytes,我可以将其提高到将近200 MiB,因为/ proc / meminfo似乎已考虑到该储备,但是为了进行测试,我将其设置为上面的水平。
要测试实际有多少RAM,我使用压力工具,如下所示:
stress --vm 11 --vm-bytes 10M --vm-keep --timeout 5s
在110 MiB时,系统保持响应状态,free和vmstat都反映出增加的RAM使用率。所报告的最低免费/可用值如下:
[root@host ~]# free -k
total used free shared buff/cache available
Mem: 249616 146580 93196 68 9840 57124
Swap: 0 0 0
[root@host ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
11 0 0 93204 1792 8048 0 0 0 0 240 679 50 0 50 0 0
这是事情开始崩溃的地方。将压力的内存使用量增加到120 MiB(仍远低于报告的168 MiB)后,系统在压力运行时冻结5秒钟。在测试期间连续运行vmstat(或由于冻结而尽可能连续运行)显示:
[root@host ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 209664 724 6336 0 0 0 0 237 666 0 1 99 0 0
3 0 0 121916 1024 6724 0 0 289 0 1088 22437 0 45 54 0 0
1 0 0 208120 1328 7128 0 0 1652 0 4431 43519 28 22 50 0 0
由于中断和IO的大量增加,我猜想内核正在逐出包含可执行代码的页面,然后立即需要从闪存读回它们。我的问题是:a)这是正确的评估吗?和b)为什么内核会在RAM仍然可用的情况下执行此操作?
请注意,如果尝试使用一个压力很大的工作程序并要求160 MiB的内存,则OOM将被激活并终止测试。在上述情况下,OOM不会触发。