Ответ 1
Может быть, что Perl никогда не возвращает память в систему сама по себе: все до malloc()
и всех правил, связанных с этим.
Знание того, как malloc()
выделяет память, важно ответить на более важный вопрос и варьироваться от системы к системе, но в целом большинство реализаций malloc()
оптимизированы для программ, распределяющих и освобождающихся от стека в виде заказов. Perl использует подсчет ссылок для отслеживания памяти, что означает, что deallocations, что означает (в отличие от языка, основанного на 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 может быть хорошим первым местом, но вы 'll нужен perl, построенный для отладки.
Если вы подозреваете, что утечка находится внутри XS-пространства, это намного сложнее, и Valgrind, вероятно, будет вашим лучшим выбором. Test:: Valgrind может помочь вам снизить количество кода, необходимого для поиска, но это не будет работать в Windows, так что вы для этого нужно портировать (по крайней мере, протекающую часть) в Linux.