Использование памяти, сообщаемое гуппи, отличается от команды ps - PullRequest
7 голосов
/ 14 января 2010

Я профилирую свой витой сервер. Он использует гораздо больше памяти, чем я ожидал. Его использование памяти растет со временем.

 ps -o pid,rss,vsz,sz,size,command
  PID   RSS    VSZ    SZ    SZ COMMAND
 7697 70856 102176 25544 88320 twistd -y broadcast.tac

Как видите, стоит 102176 КБ , а именно 99,78125 МБ . И я использую гуппи из витого люка, чтобы посмотреть профиль использования памяти.

>>> hp.heap()
Partition of a set of 120537 objects. Total size = 10096636 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  61145  51  5309736  53   5309736  53 str
     1  27139  23  1031596  10   6341332  63 tuple
     2   2138   2   541328   5   6882660  68 dict (no owner)
     3   7190   6   488920   5   7371580  73 types.CodeType
     4    325   0   436264   4   7807844  77 dict of module
     5   7272   6   407232   4   8215076  81 function
     6    574   0   305776   3   8520852  84 dict of class
     7    605   1   263432   3   8784284  87 type
     8    602   0   237200   2   9021484  89 dict of type
     9    303   0   157560   2   9179044  91 dict of zope.interface.interface.Method
<384 more rows. Type e.g. '_.more' to view.>

Хм ... Кажется, что-то не так. Гуппи показывает, что общее использование памяти составляет 10096636 байт, а именно 9859,996 КБ или 9,628 МБ .

Это огромная разница. Что плохого в этом странном результате? Что я делаю не так?

Обновление: Я написал скрипт монитора прошлой ночью. Он записывает использование памяти и количество онлайн-пользователей. Это радиосервер, так что вы можете видеть, что есть радио и общее количество слушателей. Вот рисунок, который я сгенерировал с помощью matplotlib. alt text

Что-то странное. Иногда использование памяти, напечатанное ps, очень мало, например

2010-01-15 00:46:05,139 INFO 4 4 17904 36732 9183 25944
2010-01-15 00:47:03,967 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:48:04,373 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:49:04,379 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:50:02,989 INFO 4 4 3700 5256 1314 2260

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

Ответы [ 3 ]

6 голосов
/ 14 января 2010

возможно из-за подкачки / резервирования памяти, основываясь на определении ps:

RSS: resident set size, the non-swapped physical memory
     that a task has used (in kiloBytes).

VSZ: virtual memory usage of entire process.
     vm_lib + vm_exe + vm_data + vm_stack

это может немного сбивать с толку, 4 метрики разных размеров можно увидеть с помощью:

# ps -eo pid,vsz,rss,sz,size,cmd|egrep python

PID    VSZ   RSS   SZ    SZ    CMD
23801  4920  2896  1230  1100  python

виртуальный размер включает память, которая была зарезервирована процессом и не использовалась, размер всех общих библиотек, которые были загружены, страницы, которые были выгружены, и блоки, которые уже были освобождены вашим процессом, так что он может быть намного больше чем размер всех живых объектов в питоне.

некоторые дополнительные инструменты для исследования производительности памяти:

хорошее руководство по отслеживанию утечек памяти в python с использованием pdb и objgraph:

http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks

3 голосов
/ 29 января 2010

Как указано выше, здесь больше всего интересует размер RSS. «Виртуальный» размер включает отображаемые библиотеки, которые вы, вероятно, не хотите считать.

Прошло много времени с тех пор, как я использовал heapy, но я почти уверен, что статистика, которую он печатает, не включает служебные данные, добавленные самой heapy. Эти издержки могут быть довольно значительными (я видел, как процесс RSS на 100 МБ вырос еще на дюжину или около того МБ, см. http://www.pkgcore.org/trac/pkgcore/doc/dev-notes/heapy.rst).

Но в вашем случае я подозреваю, что проблема в том, что вы используете какую-то библиотеку C, которая либо пропускает, либо использует память таким образом, что heapy не отслеживает. Heapy знает о памяти, используемой непосредственно объектами python, но если эти объекты обертывают объекты C, которые выделены отдельно, heapy обычно вообще не знает об этой памяти. Возможно, вам удастся добавить поддержку heapy к вашим привязкам (но если вы не контролируете используемые привязки, это, очевидно, хлопотно, и даже если вы контролируете привязки, вы не сможете сделать это в зависимости от того, что вы оборачиваете ).

Если есть утечки на уровне C, heapy также потеряет память об этом (размер RSS будет увеличиваться, но сообщаемый размер heapy останется прежним). Valgrind - это, вероятно, ваш лучший выбор, чтобы отследить их, как и в других приложениях на Си.

Наконец: фрагментация памяти часто приводит к тому, что использование вашей памяти (как показано сверху) увеличивается, но не уменьшается (сильно). Обычно это не такая большая проблема с демонами, так как процесс будет повторно использовать эту память, она просто не возвращается обратно в ОС, поэтому значения в верхней части не возвращаются вниз. Если использование памяти (как видно сверху) возрастает более или менее линейно с количеством пользователей (подключений), не снижается, но также не будет расти вечно, пока вы не достигнете нового максимального числа пользователей, вероятно, фрагментация винить.

1 голос
/ 12 октября 2011

Это не полный ответ, но из вашего люка я бы также предложил запустить gc.collect () вручную перед просмотром с помощью ps или top. Гуппи покажет выделенную кучу, но ничего не сделает для упреждающего освобождения объектов, которые больше не выделяются.

...