.png)
Я наблюдаю поведение, которое не могу объяснить, на моем встраиваемом Linux-целевом устройстве (initramfs инет обмена).
Поскольку подкачки нет, я бы ожидал, что все в /tmp (tmpfs) будет помечено как невыполнимое. Вместо этого я наблюдаю следующее при использовании следующего скрипта:
#!/bin/sh
count=1
while true; do
echo "#$count"
dd if=/dev/zero of=/tmp/zero$count bs=1M count=10 && cat /proc/meminfo | grep 'Unevictable\|Shmem'
count=`expr $count + 1`
sleep 3
done
При записи большого количества файлов по 10 МБ Shmem растет линейно, но неизвлекаемая память очень быстро увеличивается с 0 КБ до ~200 МБ:
#40 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.102484 seconds, 97.6MB/s Unevictable: 0 kB Shmem: 453776 kB #41 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.047640 seconds, 209.9MB/s Unevictable: 0 kB Shmem: 464196 kB #42 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.101833 seconds, 98.2MB/s Unevictable: 884 kB Shmem: 474616 kB #43 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.051686 seconds, 193.5MB/s Unevictable: 234612 kB Shmem: 485040 kB #44 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.052157 seconds, 191.7MB/s Unevictable: 238568 kB Shmem: 495572 kB #45 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.043332 seconds, 230.8MB/s Unevictable: 245332 kB Shmem: 505892 kB #46 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.042653 seconds, 234.4MB/s Unevictable: 245332 kB Shmem: 516312 kB #47 10+0 records in 10+0 records out 10485760 bytes (10.0MB) copied, 0.048478 seconds, 206.3MB/s Unevictable: 248384 kB Shmem: 526724 kB
Если я удалю все нулевые файлы, неизгоняемая память останется на том же уровне. Означает ли это, что я потерял всю эту оперативную память? Похоже на то, что OOM killer, похоже, был вызван раньше. Как мне вернуть ее?
# rm /tmp/zero* # cat /proc/meminfo | grep 'Unevictable\|Shmem' Unevictable: 288372 kB Shmem: 48412 kB
С фрагментами по 100 МБ вместо 10 МБ:
#1 100+0 records in 100+0 records out 104857600 bytes (100.0MB) copied, 0.422820 seconds, 236.5MB/s Unevictable: 0 kB Shmem: 150168 kB #2 100+0 records in 100+0 records out 104857600 bytes (100.0MB) copied, 0.471385 seconds, 212.1MB/s Unevictable: 0 kB Shmem: 252516 kB #3 100+0 records in 100+0 records out 104857600 bytes (100.0MB) copied, 0.444059 seconds, 225.2MB/s Unevictable: 0 kB Shmem: 354888 kB #4 100+0 records in 100+0 records out 104857600 bytes (100.0MB) copied, 0.414981 seconds, 241.0MB/s Unevictable: 0 kB Shmem: 457368 kB #5 100+0 records in 100+0 records out 104857600 bytes (100.0MB) copied, 5.538392 seconds, 18.1MB/s Unevictable: 288264 kB Shmem: 559700 kB #6 dd: writing '/tmp/zero6': No space left on device
Может ли кто-нибудь объяснить наблюдаемое поведение, которое, как мне кажется, является ошибкой ядра?
Спасибо
решение1
Подозреваю, что это не tmpfs, а ramfs.
Список неисключаемых страниц охватывает следующие классы неисключаемых страниц:
Те, что принадлежат ramfs.
Они отображены в
SHM_LOCK
разделяемые области памяти.Они сопоставлены с
VM_LOCKED
[mlock()ed] VMA.Инфраструктура также может быть способна обрабатывать другие условия, которые сделают страницы неизбежными либо по определению, либо в силу обстоятельств в будущем.
https://www.kernel.org/doc/Documentation/vm/unevictable-lru.txt
В ответ на ваш вопрос,Красная Шапкарезюмировать «Неизбежный» можно так: «Объем памяти в кибибайтах,обнаружен кодом pageout, который невозможно удалить, поскольку он заблокирован в памяти пользовательскими программами».
Читая полный документ, похоже, что по какой-то причине ramfs
выделения начинаются с обычного Inactive(anon)
списка LRU. Как только у вас заканчивается свободная память и вы начинаете запускать reclaim (pageout), списки сканируются, и виртуальная машина «обнаружит» заблокированную память и переместит ее в список невытесняемых.
В связи с этим, есть такжекомментарий к ядручто говорит о том, что поле «Mlocked» может не учитывать заблокированные страницы немедленно. (Возможно, в некоторых случаях это так, я не проверял).
NR_MLOCK, /* mlock()ed pages found and moved off LRU */
Я не предполагаю, что ядро сканирует весь список сразу, но предполагаю, что оно сканирует его большими пакетами.
Проблема этой теории в том, что я не знаю, почему/как ваше ядро будет сканировать списки "anon", если у вас не настроена подкачка. Я даже нашелкод-
/* If we have no swap space, do not bother scanning anon pages. */
if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
scan_balance = SCAN_FILE;
goto out;
}