有什么方法来调试内存泄漏在Perl吗?附加到程序并获得各种类型的对象数量将是一个好的开始。如果我知道哪些对象比预期的要多得多,我可以检查所有对它们的引用,并希望修复泄漏。
解决方法
知道malloc()如何分配内存对于回答更大的问题是很重要的,它从系统到系统是不同的,但是一般来说,大多数malloc()实现是针对以堆栈式顺序分配和释放的程序优化的。 Perl使用引用计数来跟踪内存,这意味着释放意味着(不同于基于GC的语言,下面使用malloc())实际上并不是很难分辨何处发生释放,以及以什么顺序。
可能你可以重组你的程序,以利用这个事实 – 通过调用undef($ old_object)显式 – 并且在正确的顺序,类似于C程序员说free(old_object)的方式;
对于长时间运行的程序(天,月等),我有加载/复制/转储周期的负载,我垃圾收集使用exit()和exec(),在其他地方不可行,我只是打包我的数据结构(使用Storable)和文件描述符(使用$ ^ F)和exec($ 0) – 通常有一个环境变量设置为$ ENV {EXEC_GC_MODE},你可能需要类似的,即使你没有任何泄漏自己只是因为Perl泄漏小块,你的系统的malloc()不能弄清楚如何回报。
当然,如果你在你的代码中有泄漏,那么我的其余建议是更相关的。它最初发布于to another question on this subject,但它没有明确涵盖长期运行的程序。
所有perl程序的内存泄漏将是一个XS持有一个引用,或一个循环数据结构。 Devel::Cycle是一个找到循环引用的好工具,如果你知道什么结构可能包含循环。 Devel::Peek可用于查找具有高于预期参考计数的对象。
如果你不知道在哪里看,Devel::LeakTrace::Fast可能是一个很好的第一名,但你需要一个perl为调试。
如果你怀疑泄漏是在XS空间内,这更困难,Valgrind可能是你最好的赌注。 Test::Valgrind可以帮助您降低搜索所需的代码量,但这不会在Windows上工作,所以你必须移植(至少泄漏部分)到Linux为了做到这一点。