Может быть важно, что Perl никогда не возвращает память системе сам по себе: все зависит от malloc()
и всех связанных с этим правил.
Знание того, как malloc()
распределяет память, важно для ответа на более важный вопрос, и это варьируется от системы к системе, но в целом большинство malloc()
реализаций оптимизированы для программ, распределяющих и освобождающих память в порядке, подобном стеку. Perl использует подсчет ссылок для отслеживания памяти, что означает, что освобождение памяти означает (в отличие от языка на основе GC, который использует malloc()
внизу), на самом деле не так уж и сложно сказать, где будет происходить освобождение, и в каком порядке.
Возможно, вы сможете реорганизовать свою программу, чтобы воспользоваться этим фактом, явно вызвав undef($old_object)
и в правильном порядке, аналогично тому, как программисты на Си говорят free(old_object);
Для длительно выполняющихся программ (дни, месяцы и т. Д.), Когда у меня много циклов загрузки / копирования / дампа, я собираю мусор с помощью exit() and exec()
, а там, где это вообще невозможно, я просто упаковываю свои структуры данных (с помощью Storable
) и файловые дескрипторы (с использованием $^F
) и exec($0)
- обычно с переменной среды, установленной как $ENV{EXEC_GC_MODE}
, и вам может понадобиться что-то подобное , даже если у вас нет собственных утечек просто потому, что Perl утекает небольшими фрагментами что ваша система malloc()
не может понять, как отдать.
Конечно, если у вас есть утечки в вашем коде, то остальные мои советы несколько более уместны. Первоначально он был размещен другому вопрос по этому поводу, но он не явно охватывал давно выполняющиеся программы.
Все утечки памяти программы Perl будут либо XS, удерживающим ссылку, либо циклической структурой данных. Devel :: Cycle - отличный инструмент для поиска циклических ссылок, если вы знаете, какие структуры могут содержать петли. Devel :: Peek можно использовать для поиска объектов с более высокой, чем ожидалось, ссылкой. считать.
Если вы не знаете, где еще искать, Devel :: LeakTrace :: Fast может быть хорошим первым местом, но вам понадобится perl, созданный для отладки.
Если вы подозреваете, что утечка находится внутри XS-пространства, это намного сложнее, и Valgrind, вероятно, будет вашим лучшим выбором. Test :: Valgrind может помочь вам уменьшить количество кода, необходимого для поиска, но это не будет работать в Windows, поэтому вам придется портировать (по крайней мере, дырявую часть) на Linux, чтобы сделать это.
person
geocar
schedule
09.01.2009