我如何在长时间运行的Perl程序中发现内存泄漏? [英] How can I find memory leaks in long-running Perl program?

查看:139
本文介绍了我如何在长时间运行的Perl程序中发现内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Perl使用GC的引用计数,并且很容易偶然发出循环引用。我发现我的程序似乎使用了越来越多的内存,并且在几天后它可能会溢出。



有什么方法可以在Perl中调试内存泄漏吗?附加程序并获取各种类型的对象将是一个好的开始。如果我知道哪些对象的数量比预期的多得多,我可以检查对它们的所有引用并希望修复泄漏。 解决方案

可能与Perl 永远将内存单独放回系统有关:它完全取决于 malloc()以及与此相关的所有规则。

知道 malloc()是如何分配内存对于回答更大的问题是重要的,并且它随系统而异,但通常大多数 malloc()实现都针对分配和释放类似堆栈的订单中的程序进行了优化。 Perl使用引用计数来跟踪内存,这意味着释放这意味着(不同于基于GC的语言,它在下面使用 malloc()),但实际上并不是那么困难<



这可能是因为你可以重新组织你的程序来利用这个事实,通过显式调用 undef($ old_object)>并以正确的顺序,以类似于C程序员说的方式 free(old_object);



对于长时间运行的程序(日,月等),我有负载/复制/收集使用 exit()和exec(),并且在其他地方不可行的地方,我简单地打包我的数据结构(使用 Storable )和文件描述符(使用 $ ^ F )和 exec($ 0) - 通常使用环境变量集像 $ ENV {EXEC_GC_MODE} ,你可能需要一些类似的 eve如果你没有任何自己的泄漏,只是因为Perl泄露了你的系统的 malloc()不能提供的小块当然,如果你在你的代码中有泄漏,那么我的其他建议就会更加相关。它最初发布到另一个这个问题上的问题,但它并没有明确地涵盖长时间运行的程序。






所有perl程序内存泄漏都可能是XS保存到引用或循环数据结构。 Devel :: Cycle 是查找循环引用的好工具,如果您知道什么是结构可能包含循环。 Devel :: Peek 可用于查找高于预期的对象引用计数。



如果您不知道还有其他地方需要注意, Devel :: LeakTrace :: Fast 可能是一个不错的第一名,但您需要一个用于调试的perl。



如果您怀疑泄漏位于XS空间内,那就更困难了,并且 Valgrind 可能会是您的最好的选择。 Test :: Valgrind 可以帮助您降低搜索所需的代码量,但是这在Windows上不起作用,所以你必须将(至少是泄漏的部分)移植到Linux上才能做到这一点。


Perl uses reference counting for GC, and it's quite easy to make a circular reference by accident. I see that my program seems to be using more and more memory, and it will probably overflow after a few days.

Is there any way to debug memory leaks in Perl? Attaching to a program and getting numbers of objects of various types would be a good start. If I knew which objects are much more numerous than expected I could check all references to them and hopefully fix the leak.

解决方案

It may be relevant that Perl never gives memory back to the system by itself: It's all up to malloc() and all the rules associated with that.

Knowing how malloc() allocates memory is important to answering the greater question, and it varies from system to system, but in general most malloc() implementations are optimized for programs allocating and deallocating in stack-like orders. Perl uses reference-counting for tracking memory which means that deallocations which means (unlike a GC-based language which uses malloc() underneath) it is actually not all that difficult to tell where deallocation is going to occur, and in what order.

It may be that you can reorganize your program to take advantage of this fact- by calling undef($old_object) explicitly - and in the right order, in a manner similar to the way C-programmers say free(old_object);

For long-running programs (days, months, etc), where I have loads of load/copy/dump cycles, I garbage-collect using exit() and exec(), and where it's otherwide unfeasible, I simply pack up my data structures (using Storable) and file descriptors (using $^F) and exec($0) - usually with an environment variable set like $ENV{EXEC_GC_MODE}, and you may need something similar even if you don't have any leaks of your own simply because Perl is leaking small chunks that your system's malloc() can't figure out how to give back.

Of course, if you do have leaks in your code, then the rest of my advice is somewhat more relevant. It was originally posted to another question on this subject, but it didn't explicitly cover long-running programs.


All perl program memory leaks will either be an XS holding onto a reference, or a circular data structure. Devel::Cycle is a great tool for finding circular references, if you know what structures are likely to contain the loops. Devel::Peek can be used to find objects with a higher-than-expected reference count.

If you don't know where else to look, Devel::LeakTrace::Fast could be a good first place, but you'll need a perl built for debugging.

If you suspect the leak is inside XS-space, it's much harder, and Valgrind will probably be your best bet. Test::Valgrind may help you lower the amount of code you need to search, but this won't work on Windows, so you'd have to port (at least the leaky portion) to Linux in order to do this.

这篇关于我如何在长时间运行的Perl程序中发现内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆