2010-12-09 1 views
2

У меня есть приложение, использующее POE, у которого около 10 сеансов, выполняющих различные задачи. Со временем приложение начинает потреблять все больше и больше ОЗУ, и это использование не уменьшается, хотя приложение простаивает в 80% случаев. Моим единственным решением в настоящее время является перезапуск процесса часто.Что я могу сделать, чтобы узнать, что заставляет мою программу потреблять много памяти с течением времени?

Мне не разрешено размещать здесь свой код, поэтому я понимаю, что получить помощь нелегко, но, может быть, кто-то может сказать мне, что я могу узнать сам?

+1

См. [Общие шаблоны утечки памяти/ссылок Perl?] (Http://stackoverflow.com/questions/2223721/common-perl-memory- reference-leak-patterns) и [Профилирование использования памяти в Perl и обнаружение утечки] (http://stackoverflow.com/questions/1359771/perl-memory-usage-profiling-and-leak-detection) и [Как найти память утечки в длительных программах Perl?] (http://stackoverflow.com/questions/429254/how-can-i-find-memory-leaks-in-long-running-perl-program) и [Есть ли какие-либо инструменты для поиска утечек памяти в моей программе Perl?] (http://stackoverflow.com/questions/295385) – Ether 2010-12-09 17:15:15

ответ

2

Не ожидайте уменьшения размера процесса. Память не возвращается в ОС до тех пор, пока процесс не завершится.

При этом, возможно, у вас есть ссылочные петли в структурах данных где-нибудь? AFAIK, сборщик мусора perl не может сортировать контрольные петли.

Используете ли вы какие-либо модули XS в любом месте? Внутри могут быть утечки.

+0

Итак, если память не будет возвращена обратно в ОС, то использование продолжит расти? Могут быть модули XS в зависимостях одного из модулей, которые я использую. Я также использую HTML :: TreeBuilder, чьи документы указывают, что я должен явно вызвать метод delete(), чтобы уничтожить его из памяти, которую я уже делаю. – perlit 2010-12-09 06:44:43

1

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

1

Похоже, Test::Valgrind - это инструмент для поиска утечек памяти. Я никогда не использовал его сам (но я использовал простой valgrind с источником C).

1

Один из методов - периодически выгружать содержимое $ POE :: Kernel :: poe_kernel в файл с указанием времени или последовательности. $ poe_kernel - это корень дерева, охватывающего все известные сеансы и содержимое их куч. Снимки должны монотонно расти, если ссылается на пропущенную память. Вы сможете узнать, что происходит, если сравнить ранний снимок с более поздним.

Вы можете экспортировать POE_ASSERT_DATA = 1, чтобы включить проверку целостности внутренних данных POE. Я не ожидаю, что это вызовет проблемы с поверхностью, но если это произойдет, я буду очень рад получить отчет об ошибке.

1

Perl не может разрешить опорные кольца. Либо у вас есть зомби (которые вы можете обнаружить через ps axl), либо у вас есть утечка памяти (опорные кольца/круг)

Существует множество программ для обнаружения утечек памяти. strace, mtrace, Devel :: LeakTrace :: Fast, Devel :: Cycle