我有一个存在内存泄漏的脚本。我相信这是因为在我undef
对嵌套对象执行之后,脚本中的内存量没有改变。我已经使用Devel::Cycle来定位任何循环引用,并且我已经将这些循环引用转换为带有Scalar::Util
. 问题仍然存在。
现在我正在尝试使用 Valgrind 来解决这个问题。作为 valgrind 的第一次开始,我测试了一个 perl hello world 程序:
#! /usr/bin/perl
use strict;
use warnings;
print "Hello world!\n";
这是运行时的 valgrind 输出valgrind --trace-children=yes perl ./hello_world.pl
:
==12823== HEAP SUMMARY:
==12823== in use at exit: 290,774 bytes in 2,372 blocks
==12823== total heap usage: 5,159 allocs, 2,787 frees, 478,873 bytes allocated
==12823==
==12823== LEAK SUMMARY:
==12823== definitely lost: 13,981 bytes in 18 blocks
==12823== indirectly lost: 276,793 bytes in 2,354 blocks
==12823== possibly lost: 0 bytes in 0 blocks
==12823== still reachable: 0 bytes in 0 blocks
==12823== suppressed: 0 bytes in 0 blocks
==12823== Rerun with --leak-check=full to see details of leaked memory
==12823==
==12823== For counts of detected and suppressed errors, rerun with: -v
==12823== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
从这里我的理解是,当数量allocs
不等于你的数量时,frees
就会发生内存泄漏。
由于我所做的只是打印 hello world,我不得不问一个问题,Perl 解释器本身,这里是 v5.10.1,是否至少有它自己的内存泄漏或者我解释的东西都错了?
在处理我的实际 perl 脚本之前,我想了解这一点。
附录
我在Perl 5.12.0 delta中看到以下内容:
对哈希的弱引用会泄漏。这影响了 DBI [RT #56908]。
这最终可能适用于我完整的 perl 脚本,而不是这个 hello world 程序,但它让我认为我应该经历以非 root 身份安装最新版本的 perl 的痛苦。
附录2
我安装了 activestate perl 5.16.3,问题以及我实际脚本的问题仍然存在。
我怀疑在这个 hello world 程序的情况下,我必须不正确地使用/解释 valgrind,但我还不明白在哪里。
UPDATE1 Daxim 的回答确实有所作为。当我在我的 perl 脚本中引入以下行时:
use Perl::Destruct::Level level => 1;
那么valgrind的输出是:
==29719== HEAP SUMMARY:
==29719== in use at exit: 1,617 bytes in 6 blocks
==29719== total heap usage: 6,499 allocs, 6,493 frees, 585,389 bytes allocated
==29719==
==29719== LEAK SUMMARY:
==29719== definitely lost: 0 bytes in 0 blocks
==29719== indirectly lost: 0 bytes in 0 blocks
==29719== possibly lost: 0 bytes in 0 blocks
==29719== still reachable: 1,617 bytes in 6 blocks
==29719== suppressed: 0 bytes in 0 blocks
==29719== Rerun with --leak-check=full to see details of leaked memory
==29719==
==29719== For counts of detected and suppressed errors, rerun with: -v
==29719== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
这是一个很大的区别。我自己的脚本内存泄漏问题仍然存在,但至少这个 hello world 程序现在对 valgrind 来说似乎是明智的。
这整个事情虽然引出了一个问题,Scalar::Util
如果在程序退出之前没有释放内存,那么停止硬循环引用有什么意义呢Perl::Destruct::Level
?