Я работаю над встраиваемыми целями Linux (32-битная ARM) и мне нужно определить, сколько ОЗУ доступно для приложений после запуска ядра и основного программного обеспечения. Свободная память, сообщаемая free, и / proc / meminfo, похоже, не совпадают с тем, что на самом деле показывают тестовые приложения. Есть ли способ правильно рассчитать, сколько оперативной памяти действительно доступно, без работы, например, нагрузки на каждую систему?
Целевая система, используемая в моих тестах ниже, имеет 256 МБ ОЗУ и не использует подкачку (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 МБ. Путем настройки sysctl vm.min_free_kbytes я могу увеличить это значение почти до 200 МБ, поскольку / proc / meminfo, похоже, учитывает этот резерв, но для тестирования я оставил его установленным, как указано выше.
Чтобы проверить, сколько оперативной памяти было фактически доступно, я использовал инструмент стресса следующим образом:
stress --vm 11 --vm-bytes 10M --vm-keep --timeout 5s
При 110 МБ система остается отзывчивой, и как free, так и vmstat отражают увеличение использования ОЗУ. Самые низкие сообщаемые свободные / доступные значения ниже:
[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 МБ - все еще в 168 МБ, о которых сообщается, что она доступна, система зависает на 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
Из-за значительного увеличения числа прерываний и операций ввода-вывода, я предполагаю, что ядро высвобождает страницы, содержащие исполняемый код, а затем быстро требует их считывания с флэш-памяти. Мои вопросы: а) это правильная оценка? и б) зачем ядру делать это с доступной оперативной памятью?
Обратите внимание, что если попытаться использовать одного работника со стрессом и потребовать 160 МБ памяти, OOM активируется и убивает тест. OOM не срабатывает в сценариях, описанных выше.