LINUX.ORG.RU

Об особенностях учёта потребления памяти

 , , ,


0

1

Ситуация:

Была запущена opera, которая жрёт 6 гигов, + была запущена игруля. В результате система вытеснила Оперу и всё ненужное в своп. Теперь закрываем игрулю, а затем закрываем Оперу.

Остаётся вот такая картина:

vadim@aquila:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:           15906        1647       13367         711        1915       14259
Swap:           8191        4887        3304

Как видно, занято 4887 метров в свопе. Я уже знаю, что это течёт моя программа, но суть тут в том, что смотрим как работает учёт потребления памяти. Вырубаем своп:

vadim@aquila:~$ sudo swapoff -a
[sudo] пароль для vadim: 
vadim@aquila:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:           15906        6511        8494        5139        6351        9395
Swap:              0           0           0

Теперь вся утёкшая память загружена из свопа обратно в ОЗУ. И она, внезапно, в секции shared. И при этом она же — в секции «buff/cache»! А вот это неожиданно.

Смотрим разницу показателей, цифры бьются логично:

buff/cache 6351 - 1915 =  4436
shared     5139 - 711  =  4428
used       6511 - 1647 =  4864
swap used  0    - 4887 = -4887

Теперь смотрим htop:

https://ibb.co/QYqJGbG

И как видно, в htop нет большого объёма «buff/cache». Он понимает, что «buff/cache» и shared дублируют друг друга.

И также видно, что утёкшая память не отображается ни в RESIDENT, ни в SHARED, ни даже в VIRTUAL ни одного процесса. Она есть, она учитывается системой как занятая, но её нет в счётчиках показателей потребления памяти процессов.

Теперь убиваем виновника:

vadim@aquila:~$ killall stuurman-desktop
vadim@aquila:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:           15906        1782       13214         442        1663       14124
Swap:              0           0           0

Смотрим разницу показателей, вот столько памяти у нас освободилось:

buff/cache 6351 - 1663 = 4688
shared     5139 - 442  = 4697
used       6511 - 1782 = 4729

Итак, пока только один вывод:

  • Реальное потребление памяти процессом может быть никак не связано с числами, которые htop показывает для процесса.

И остались открытые вопросы:

  1. Что именно показывает free и что именно показывает htop для общесистемных показателей. Придётся заглянуть в код, чтобы узнать точно.
  2. Как при таких условиях искать источник большого потребления ОЗУ в случае, если у нас нет возможности убивать все подозреваемые процессы подряд.
  3. А, ну и чуть не забыл. Надо всё-таки найти и исправить утечку в моём коде… когда-нибудь уже.
★★

Последнее исправление: wandrien (всего исправлений: 3)

Есть вариант, что это так учитывается потребление видеопамяти, которая у встройки общая с системной.

То есть stuurman-desktop течёт через иксы, иксы выделяют память для буферов изображений, а та память учитывается ядром как shared.

wandrien ★★
() автор топика
Последнее исправление: wandrien (всего исправлений: 1)
#!/bin/bash
ps axo rss,comm,pid \
| awk '{ proc_list[$2]++; proc_list[$2 "," 1] += $1; } \
END { for (proc in proc_list) { printf("%d\t%s\n", \
proc_list[proc "," 1],proc); }}' | sort -n | tail -n 25 | sort -rn \
| awk '{$1/=1024;printf "%.0fMB\t",$1}{print $2}'
anonymous
()
Ответ на: комментарий от anonymous

какого у тебя одновременно pulseaudio и pipewire, когда для pipewire должно использоваться pipewire-pulse

Не знаю. У меня 10 лет назад было настроено pulseaudio, с тех пор ничего не трогал. Это какие-то дефолты в Арч прилетели с апдейтами. Так как звук воспроизводится точно так же, как раньше, мне лень вникать.

wandrien ★★
() автор топика

И free и htop показывают числа из /proc/meminfo но вероятно по-разному пересчитанные. Однако это разумеется не ответ на вопрос что всё это значит - ведь числа в meminfo появляются из ядерного кода, возиться с которым тебе вряд ли захочется.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Сорцы ядер Linux и NetBSD мне грепать не впервой. Вот недавно, когда надо было понять, что именно NetBSD сообщает о потреблении памяти, погрепал, не обломался.

Впрочем, прямо сейчас больше чем навык грепа, для меня актуально желание поспать.

Так что может потом.

wandrien ★★
() автор топика
Ответ на: комментарий от firkax

Недописал.

Итак, пока только один вывод:

Вывод весьма баянистый, но его стоит обобщить - в современных ОС учёт потребления памяти вообще плохой.

В частности, это причина почему утилиты показывают разные числа - в первоисточнике половины этих чисел нет, а есть всякая муть, из которой они по косвенным признаком могут быть посчитаны.

Интересная задача: посчитать потребление памяти группой процессов.

Учитывая, разумеется, что память у них может быть как приватная, так и расшаренная, а расшаренная может быть как внутри группы так и куда-то наружу. А так же учесть, что если прога сделала mmap какого-то файла, то по факту она его кешом неизвестного размера тоже потребляет память не хуже чем обычными аллокациями - ведь и обычные аллокации можно убрать в свап на диск.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Ну для этого надо прям адресное простраство анализировать.

А так, чтобы предоставить какую-то объективную картину по итогам такого анализа, я бы наверное разбил на такие группы:

  • Анонимная память.
  • Запамять, замапленная из исполняемых файлов.
  • Чистая память, замапленная из прочих файлов.
  • Грязная память, замапленная из прочих файлов.
wandrien ★★
() автор топика

что именно показывает htop

У тебя же zswap? Не знаю, в тему ли, но @intelfx говорил, что прикрутил к htop статистику zswap:

Да, я прикрутил.

Верить htop-у. В линуксе zswap-нутые страницы учитываются так, как будто они в свопе (т. е. декрементируют SwapFree), но на самом деле они физически не в свопе. Поэтому для получения правильных (соответствующих здравому смыслу) показателей из SwapTotal-SwapFree нужно вычитать Zswapped.
Коммент

И:

Или собрать htop из мастера, я там понаписал парсер статистики zswap.
Коммент

krasnh ★★★
()
Ответ на: комментарий от krasnh

https://ibb.co/T8D1YMq - frontswap - это оно? Вроде теперь оно растёт перед реальной выгрузкой данных на накопитель.

У меня не тот случай, реально 4.8 гига было выгружено в своп из-за отсутствия оперативки.

(На самом деле до закрытия оперы, там еще и почти вся опера сидела с 30+ окнами.)

wandrien ★★
() автор топика
Ответ на: комментарий от krasnh

Кстати сказать.

Я помню, как около 20 лет назад (в 1-й половине 2000-х), я говорил: хорошо бы, если бы ядро умело сжимать страницы in-place вместо выгрузки в своп, это здорово бы улучшило работу на малом объеме памяти.

А мне некоторые отвечали: «ты что дурак? во первых, оно не будет эффективно сжиматься, а во-вторых, будет тормозить!» И дальше что-нибудь про нищебродов и про докупить RAM под задачи.

А потом глядишь, прошло не так много лет, и в ядро запилили сначала zram, а потом и zswap.

На самом деле таких хороших идей – полно (не только у меня, вообще в мире вокруг), просто до их реализации еще не дошел черёд.

wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

У меня не тот случай, реально 4.8 гига было выгружено в своп из-за отсутствия оперативки.

Как ты это можешь гарантировать?

В следующий раз посмотри/покажи ещё выхлоп zswap-monitor2.py

greenman ★★★★★
()
Последнее исправление: greenman (всего исправлений: 1)
Ответ на: комментарий от wandrien

Что бы посмотреть, что там во zswap-е

Например, как бывает:

pool: 138.8 MiB (3.6% MemTotal) | stored: 886.2 MiB (98.3% SwapUsed) | compr_ratio: 6.4

При этом эти 886 и в swapon отображаются.

greenman ★★★★★
()
Последнее исправление: greenman (всего исправлений: 1)