Использование памяти, о котором сообщает guppy, отличается от команды ps.

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

 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.>

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

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

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

Что-то странное. Иногда использование памяти, напечатанное 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

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


person Fang-Pen Lin    schedule 14.01.2010    source источник


Ответы (3)


возможно, из-за резервирования подкачки/памяти, исходя из определения 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.

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

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

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

person jspcal    schedule 14.01.2010
comment
Но даже я сравниваю 69 Мб с 10 Мб, это уже слишком. В чем может быть проблема? Более того, использование памяти со временем растет. Сначала размер RSS составлял примерно 2xMB, а сейчас он достигает 6x. - person Fang-Pen Lin; 14.01.2010
comment
некоторые из объектов, о которых сообщает guppy, могут быть заменены, поэтому python может сообщать о них, в то время как rss не будет включать их ... я не уверен, почему процесс резервирует так много памяти, может быть, тонны общих библиотек ...? - person jspcal; 14.01.2010
comment
Все библиотеки загружаются при запуске. Он использует только 2x МБ в поле RSS при запуске сервера. Нет смысла в том, что библиотеки занимают дополнительную память. Есть ли способ узнать, что такое использование невидимой памяти? - person Fang-Pen Lin; 14.01.2010
comment
хм, похоже, где-то происходит утечка памяти, можете ли вы попробовать Python Memory Validator, чтобы точно определить, какой код выделяет больше всего памяти? - person jspcal; 14.01.2010

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

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

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

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

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

person mzz    schedule 29.01.2010

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

person some guy    schedule 11.10.2011