Может иметь значение, что Perl никогда сам не возвращает память системе: все до malloc()
и все правила, связанные с этим.
Знание того, как malloc()
выделяет память, важно для ответа на больший вопрос, и оно варьируется от системы к системе, но в целом большинство реализаций malloc()
оптимизированы для программ, выделяющих и освобождающих их в виде стеков. Perl использует подсчет ссылок для отслеживания памяти, что означает, что освобождение памяти означает, что (в отличие от языка на основе GC, который использует malloc()
внизу), на самом деле не так сложно сообщить , где произойдет освобождение, и в каком порядке.
Возможно, вы сможете реорганизовать свою программу, чтобы воспользоваться этим фактом - явно вызвав undef($old_object)
и в правильном порядке, способом, подобным тому, как говорят программисты C 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, чтобы сделать это.