Вопросы по использованию памяти в Perl - PullRequest
3 голосов
/ 18 октября 2011

ТАК сообщество,

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

Сомнительное наблюдение # 1:

Я запускаю один и тот же сценарий perl на разных экземплярах сервера (локальный ноутбук Macosx, оборудование для выделенного сервера, оборудование для виртуального сервера) и получаю значительно отличающиеся результатыв отслеживаемом потреблении памяти.Сразу после инициализации скрипта один экземпляр сообщит, что потребление скрипта составляет 210 МБ, а в другом боксе - 330 МБ, что составляет более 60%.Я понимаю, что функция malloc (), отвечающая за "сборку мусора" для Perl, зависит от конкретной ОС, но есть ли отклонения в норме или я должен более внимательно следить за происходящим?

Сомнительное наблюдение # 2:

Один сценарий с утечками памяти является относительно тривиальным:

foreach(@dataSamples) {

  #memorycheck_1

  my $string = subRoutine($_);
  print FILE $string;

  #memorycheck_2

}

Все переменные в подпрограмме остаются локальными и должны выходить из области видимости после завершения подпрограммы.Однако при проверке использования памяти в # memorycheck_1 и # memorycheck_1 происходит значительная утечка памяти.

Есть ли какое-либо объяснение этому?Используя Devel :: Leak, кажется, что есть просочившиеся указатели, которые мне трудно понять, откуда они берутся.Есть ли простой способ перевести ответ Devel :: Leak во что-то, что действительно может дать мне указатели, откуда берутся эти просочившиеся ссылки?

Спасибо

Ответы [ 2 ]

3 голосов
/ 18 октября 2011

Наиболее распространенная причина утечки памяти в Perl - циклические ссылки.Простейшей формой было бы что-то вроде:

sub subRoutine {
    my( $this, $that );
    $this = \$that;
    $that = \$this;
    return $_[0];
}

Теперь, конечно, люди, которые читают, вероятно, говорят: «Зачем кому-то это делать?»И один, как правило, не будет.Но более сложные структуры данных могут содержать циклические ссылки довольно легко, и мы даже не моргнем на них.Рассмотрим двойные списки, где каждый узел ссылается на узел слева и справа от него.Важно не допустить, чтобы последняя явная ссылка на такой список вышла из области видимости, не нарушив предварительно циклические ссылки, содержащиеся в каждом из его узлов, иначе вы получите структуру, которая недоступна, но не может быть собрана сборщиком мусора, поскольку ссылкачисло для каждого узла никогда не падает до нуля.

За Отличное предложение Эрика Строма , модуль ядра Scalar::Util имеет функцию под названием weaken.Ссылка, которая была ослаблена, не будет содержать счетчик ссылок на сущность, на которую она ссылается.Это может быть полезно для предотвращения циркулярных ссылок.Другая стратегия заключается в реализации вашей структуры данных с круговой ссылкой в ​​классе, где метод объекта явно нарушает циклическую ссылку.В любом случае, такие структуры данных требуют тщательной обработки.

Еще один источник проблем - плохо написанные XS-модули (ничего против авторов XS; просто очень сложно хорошо писать XS-модули).То, что происходит за закрытыми дверями модуля XS, может быть утечкой памяти.

Пока мы не увидим, что происходит внутри subRoutine, мы можем только догадываться, действительно ли существует проблема, и каков источникпроблема может быть.

3 голосов
/ 18 октября 2011

У вас есть два разных вопроса:

1) Почему объем памяти не одинаков в разных средах?

Хорошо, все ли 64-битные ОС задействованы?Или есть смесь?Если одна ОС 32-битная, а другая 64-битная, то следует ожидать изменений.Или, как отмечает @hobbs в комментариях, один из perl скомпилирован с поддержкой потоков, а другой нет?

2) Почему объем памяти изменяется между проверкой № 1 и № 2?

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

Ни один из этих пунктов не относится к Perl.Для более подробной информации вам нужно показать более подробную информацию.

См. Также Вопрос 7.25 в C FAQ и дальнейшее чтение , упомянутое в этой записи FAQ.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...