Подтвердить что ты не робот

Как найти источник увеличения использования памяти скрученного сервера?

У меня есть сервер аудио трансляции, написанный на Python и основанный на Twisted. Он работает нормально, но его использование памяти увеличивается, когда на сервере больше пользователей, но использование памяти никогда не снижается, когда эти пользователи отключаются. Как вы видите на следующем рисунке: alt text

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

Я попробовал следующий метод для решения этой проблемы:

  1. Обновление Twisted с 8,2 до 9,0
  2. Используйте гуппи, чтобы сбросить кучу, но это совсем не помогает
  3. Переключите реактор селектора на реактор Эполла, та же проблема.
  4. Используйте objgraph, чтобы нарисовать диаграмму отношения объектов, но я не вижу точек из этого.

Вот среда, которую я использовал для запуска своего скрученного сервера:

  • Python: 2.5.4 r254: 67916
  • ОС: Linux версии 2.6.18-164.9.1.el5PAE ([email protected]) (версия gcc 4.1.2 20080704 (Red Hat 4.1.2-46))
  • Витая: 9,0 (под virtualenv)

Свалка гуппи:

Partition of a set of 116280 objects. Total size = 9552004 bytes.
 Index  Count   %     Size   % Cumulative  % Type
  0  52874  45  4505404  47   4505404  47 str
  1   5927   5  2231096  23   6736500  71 dict
  2  29215  25  1099676  12   7836176  82 tuple
  3   7503   6   510204   5   8346380  87 types.CodeType
  4   7625   7   427000   4   8773380  92 function
  5    672   1   292968   3   9066348  95 type
  6    866   1    82176   1   9148524  96 list
  7   1796   2    71840   1   9220364  97 __builtin__.weakref
  8   1140   1    41040   0   9261404  97 __builtin__.wrapper_descriptor
  9   2603   2    31236   0   9292640  97 int

Как видите, общий размер 9552004 байта составляет 9,1 МБ, и вы можете увидеть rss, переданное командой ps:

[[email protected] ~]$ ps -u xxxx-o pid,rss,cmd
  PID   RSS CMD
22123 67492 twistd -y broadcast.tac -r epoll

Rss моего сервера составляет 65,9 МБ, это означает, что на моем сервере используется невидимая память 56,8 МБ, что это?

Мои вопросы:

  1. Как найти источник увеличения использования памяти?
  2. Какое видное использование памяти для гуппи?
  3. Что это за невидимое использование памяти?
  4. Это вызвано утечками памяти некоторых модулей, написанных на C? Если это так, как я могу отследить и исправить это?
  5. Как Python управляет памятью? Пул памяти? Я думаю, что это может быть вызвано кусками аудио данных. Так что есть небольшие утечки памяти, принадлежащие интерпретатору Python.

Обновление 2010/1/20: Интересно, я загружаю последний файл журнала, и это показывает, что память никогда не увеличивается с момента. Я думаю, может быть, выделенное пространство памяти достаточно велико. Вот последняя цифра. alt text

Обновление 2010/1/21: еще одна фигура здесь. гул.... поднять немного alt text

Упс... Все еще идет вверх alt text

4b9b3361

Ответ 1

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

  1. размер куска 511
  2. размер куска 1040
  3. размер куска 386
  4. размер куска 1350
  5. ...

Большинство из них имеют размер более 256 байт, Python использует malloc для блоков размером более 256 байт, а не использует пул памяти. И вы можете представить, что эти куски выделены и освобождены, что случилось бы? Например, когда освобождается блок размером 1350, в куче может быть свободное пространство 1350 байт. После этого, вот еще один запрос 988, как только malloc выберет отверстие, а затем появится еще одно новое маленькое свободное отверстие размером 362. После долгого пробега в кучах появляется все больше маленьких отверстий, другими словами, много фрагментов в кучах. Размер страницы виртуальной памяти обычно составляет 4 КБ, эти фрагменты распределены по большому диапазону кучи, это делает ОС не способной выгружать эти страницы. Таким образом, RSS всегда высоко.

После модификации конструкции модуля управления аудиоблоками моего сервера он теперь использует мало памяти. Вы можете увидеть рисунок и сравнить с предыдущим.

alt text

Новый дизайн использует bytearray, а не список строк. Это большой кусок памяти, поэтому больше нет фрагментации.

Ответ 2

Это звучит как утечка памяти в модуле C для меня. Valgrind - хороший инструмент для отслеживания проблем, связанных с распределением памяти. Я не знаю, насколько это хорошо работает с загруженными во время загрузки модулями, хотя...

Ответ 3

Вы думали об использовании альтернативы CentOS для dtrace - SystemTap Я думаю, что ее вызвали.

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

Интересный вопрос. С нетерпением ждем других ответов.

Бен