Очень высокое использование кэша, вызывающее замедление
Я пытаюсь определить виновника того, что делает мой персональный компьютер крайне вялым. Самый большой подозреваемый это память. Когда компьютер работает быстро, моя кеш-память выглядит нормально. Однако, когда он работает медленно, это выглядит так:
luke@Luke-XPS-13:~$ free -m
total used free shared buff/cache available
Mem: 7830 1111 1090 277 5628 1257
Swap: 16077 665 15412
и это:
luke@Luke-XPS-13:~$ vmstat -S M
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 665 1065 67 5562 0 0 34 88 43 23 13 4 82 0 0
Кэши занимают 5,5 ГБ моей 8 ГБ памяти, когда все программы закрыты и после запуска
echo "echo 3 > /proc/sys/vm/drop_caches"
которая должна быть силой, очищающей их. Как только компьютер начинает погружаться в своп, его игра заканчивается на приемлемой скорости. Выключение временно устраняет проблему, но в конечном итоге она возвращается, и я не могу понять, что ее вызывает. Slabtop рассказывает немного больше о виновнике, но я не уверен, что это означает. Зачем kmalloc-4096
?
Active / Total Objects (% used) : 1554043 / 1607539 (96.7%)
Active / Total Slabs (% used) : 167569 / 167569 (100.0%)
Active / Total Caches (% used) : 76 / 109 (69.7%)
Active / Total Size (% used) : 5091450.96K / 5105920.97K (99.7%)
Minimum / Average / Maximum Object : 0.01K / 3.18K / 18.50K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
1254755 1254755 100% 4.00K 156847 8 5019104K kmalloc-4096
5430 5430 100% 2.05K 362 15 11584K idr_layer_cache
20216 9010 44% 0.57K 722 28 11552K radix_tree_node
8820 7358 83% 1.05K 294 30 9408K ext4_inode_cache
38577 25253 65% 0.19K 1837 21 7348K dentry
12404 11432 92% 0.55K 443 28 7088K inode_cache
30120 29283 97% 0.20K 1506 20 6024K vm_area_struct
31722 31722 100% 0.12K 933 34 3732K kernfs_node_cache
13696 12514 91% 0.25K 856 16 3424K kmalloc-256
27144 27134 99% 0.10K 696 39 2784K buffer_head
41088 29789 72% 0.06K 642 64 2568K kmalloc-64
632 567 89% 3.75K 79 8 2528K task_struct
2432 2274 93% 1.00K 152 16 2432K kmalloc-1024
3048 2677 87% 0.64K 127 24 2032K shmem_inode_cache
912 845 92% 2.00K 57 16 1824K kmalloc-2048
172 162 94% 8.00K 43 4 1376K kmalloc-8192
1736 1561 89% 0.56K 62 28 992K ecryptfs_key_record_cache
5103 4073 79% 0.19K 243 21 972K kmalloc-192
1792 1626 90% 0.50K 112 16 896K kmalloc-512
1456 1456 100% 0.61K 56 26 896K proc_inode_cache
10149 8879 87% 0.08K 199 51 796K anon_vma
24960 19410 77% 0.03K 195 128 780K kmalloc-32
360 352 97% 2.06K 24 15 768K sighand_cache
3 ответа
Исходя из ваших комментариев, вы говорите, что использование кэша заметно не падает, когда вы пытаетесь echo 3 > /proc/sys/vm/drop_caches
Это может произойти, только если это кеш для записи. Если вы записываете 5 ГБ в некоторые файлы, данные немедленно попадают в кэш, и ваша программа продолжается. Кеш на самом деле записывается в хранилище в фоновом режиме как можно быстрее. В вашем случае хранилище кажется очень медленным, и вы накапливаете неписанный кеш, пока он не истощит всю вашу оперативную память и не начнет выталкивать все из памяти для замены.
Ядро никогда не запишет кеш в раздел подкачки. Он хранит его в оперативной памяти, пока он не будет безопасно записан в место назначения.
Ядро никогда не удалит неписанный кеш, потому что это приведет к потере данных (вы сохранили файл, поэтому вы ожидаете, что данные попадут в постоянное хранилище).
Вы можете решить это только за счет ускорения хранения. Эта проблема часто наблюдается в хранилище, смонтированном по сети (проверьте mount
для типов cifs
, nfs
, sshfs
и т. д.) или медленные устройства USB1.
Вы также можете сделать проблему гораздо менее существенной для системы, закрыв грязный кеш sysctl vm.dirty_ratio=10
прежде чем он станет слишком много.
dirty_ratio
Содержит в процентах от общей доступной памяти, содержащей свободные страницы и исправляемые страницы, количество страниц, на которых процесс, генерирующий запись на диск, сам начнет записывать грязные данные.
Общая доступная память не равна общей системной памяти.
Если это правильный диагноз, вы увидите, что кеш легко удаляется (по крайней мере, на 90%) и что процесс записи этих гигабайт становится очень медленным. Остальная часть системы станет более отзывчивой.
Свободная память выделяется для дискового кэша. Это нормально.
Медлительность, вызванная использованием свопа, также является нормальной. Тем не менее, ваш своп примерно вдвое больше необходимого размера.
Вы можете попробовать установить vm.swappiness
параметр, чтобы попытаться сбалансировать использование свопа и дискового кэша.
Сразу после перезагрузки, попробовать на лету, в terminal
тип:
sudo sysctl -w vm.swappiness=10
Если это поможет, сделайте его постоянным, отредактировав:
gksudo gedit /etc/sysctl.conf
и добавление:
# adjust swap vs ram ratio, default=60
vm.swappinesss=10
до конца файла сохраните и выйдите, перезагрузите компьютер.
Я бы порекомендовал пару вещей:
Проверять
cat /proc/meminfo
и осматривать иShmem
. Если вы запускаете программное обеспечение, которое использует много разделяемой памяти, это будет учитыватьсяCached
но это не кеш в традиционном смысле, от которого можно отказаться, когда потребуется больше оперативной памяти. Подробности см. в обсуждении на странице https://lkml.org/lkml/2021/8/30/635 . Обычно это лучший показатель реально используемой памяти, которую можно получить, немедленно удалив все возможные кэши и используя всю свободную память вместе. Обратите внимание, чтоMemAvailable
является статистикой, а не точным значением, поэтому оно может немного отставать при очень интенсивном использовании памяти.Попробуйте увеличить
/proc/sys/vm/vfs_cache_pressure
. По умолчанию это100
но если вам немного не хватает памяти, вы можете попробовать увеличить это (например,echo 150 > /proc/sys/vm/vfs_cache_pressure
в качествеroot
). Теоретически это должно снизить производительность, чтобы увеличить доступную для приложений оперативную память за счет уменьшения дискового кэширования. Это уменьшит общую пропускную способность вашего диска, но может уменьшить задержку в худшем случае в случаях, когда оперативной памяти становится мало.Бежать
cat /proc/buddyinfo
и убедитесь, что у вас есть свободные блоки для всех размеров блоков. В основном любые строки со словомNormal
не должно быть нуля ни в одном столбце. Если у вас есть нули, особенно ближе к концу строки, и большие числа в начале, ваша система страдает от фрагментации памяти. Если вы страдаете от фрагментации памяти, попробуйте запуститьecho 1 > /proc/sys/vm/compact_memory
. Если это помогает повысить производительность системы на короткое время, ваша система страдает от фрагментации памяти, и вам следует попытаться либо использовать больше мощности ЦП для более частого автоматического сжатия памяти, либо исправить программное обеспечение, вызывающее сильную фрагментацию. Некоторые люди заканчивают тем, что добавляютcron
работа для эха 1 дляcompact_memory
каждые N минут, но я считаю, что это грубый обходной путь, а не реальное исправление.