Нахождение утечки памяти Perl - PullRequest
7 голосов
/ 02 ноября 2009

решено см. Редактировать 2

Здравствуйте,

Я пишу программу на Perl для автоматического обновления локальных (проприетарных) программ (для компании, в которой я работаю).

По сути, он работает через cron и, к сожалению, имеет утечку памяти (или что-то подобное). Проблема в том, что утечка происходит только тогда, когда я не смотрю (иначе при запуске через cron, а не через командную строку).

Мой код не содержит циклических (или других) ссылок, поэтому часто цитируемые инструменты мне не помогут (Devel::Cycle, Devel::Peek).

Как мне узнать, что использует столько памяти, что ядро ​​ убивает ее ?

Обычно SFTP-код на сервере (используя `` `sftp ...` ``), вызывает OpenSSL для проверки файла, а затем еще больше SFTP, если нужно больше файлов, и устанавливает их (снимает их).

Я видел задержки (~ 15 секунд) перед первым сеансом SFTP, но он никогда не использовал столько памяти, сколько мог быть уничтожен (в моем присутствии).

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

Редактировать: Следующее сообщение распечатано ядром, что привело меня к мысли, что это утечка памяти:

[100023.123] Out of memory: kill process 9568 (update.pl) score 325406 or a child
[100023.123] Killed Process 9568 (update.pl)

Я не верю, что это проблема cron из-за останова (иногда на ~ 15 секунд) при запуске через командную строку. Кроме того, не используются никакие переменные среды (по крайней мере, из-за того, что я написал, может быть, из-за чего это делается?)

Редактировать 2: Я нашел проблему самостоятельно, с помощью комментария ниже, написанного mobrule (в ответ на этот вопрос). Оказывается, что скрипт вызывался из crontab пользователя (без полномочий root) только один раз в день и что (привилегии без полномочий root) вызывали особую ситуацию с бесконечным циклом.

Извините, ребята, я чувствую себя немного глупо, что не нашел этого раньше, но спасибо.

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

Окончание редактирования

Спасибо, Brian

P.S. Я могу публиковать небольшие фрагменты кода, но не все из-за политики компании.

Ответы [ 3 ]

5 голосов
/ 03 ноября 2009

Вы можете попробовать использовать Devel :: Size для профилирования некоторых ваших объектов. например в области действия main:: (сам файл .pl) сделайте что-то вроде этого:

use Devel::Size qw(total_size);

foreach my $varname (qw(varname1 varname2 ))
{
    print "size used for variable $varname: " . total_size($$varname) . "\n";
}

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

Другие вещи, которые нужно попробовать:

  • Поочередно устраняйте частички функциональности, чтобы увидеть, вдруг ли ситуация станет намного лучше; Я бы начал с использования любых внешних библиотек
  • Неправильное поведение локализовано только на одной конкретной машине или одной конкретной операционной системе? Переместите программу в другие системы, чтобы увидеть, как меняется ее поведение.
  • (При отдельной установке) попробуйте обновить до последней версии Perl (5.10.1), а также обновить все ваши модули CPAN
1 голос
/ 02 ноября 2009

Откуда ты знаешь, что это утечка памяти? Я могу подумать о многих других причинах, по которым ОС убивает программу.

Первый вопрос, который я хотел бы задать: «Всегда ли эта программа работает правильно из командной строки?». Если ответ «Нет», я бы сначала решил эти проблемы.

С другой стороны, если ответ «Да», я бы исследовал все различия между выполнением программы под управлением cron и из командной строки, чтобы выяснить, почему она работает неправильно.

1 голос
/ 02 ноября 2009

Если он запускается cron, то не должен ли он умереть после итерации? Если это так, мне трудно понять, насколько серьезной будет утечка памяти ...

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

...