我的脚本存在内存泄漏。我相信是因为在对嵌套对象执行undef之后,脚本中的内存量保持不变。我已经使用Devel::Cycle来定位任何循环引用,并且已经使用Scalar::Util将这些循环引用转换为弱引用。问题仍然存在。

现在,我正在尝试使用Valgrind解决此问题。首先从valgrind开始,我在perl hello world程序中测试了一些东西:

#! /usr/bin/perl

use strict;
use warnings;

print "Hello world!\n";


这是运行valgrind --trace-children=yes perl ./hello_world.pl时的valgrind输出:

==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)


我从here的理解是,当allocs的数量不等于frees的数量时,就会发生内存泄漏。

由于我所做的只是打印hello world,因此我不得不问这个问题,Perl解释器本身(这里是v5.10.1)是否至少有其自身的内存泄漏,或者我解释的东西全都错了吗?

在处理我的实际Perl脚本之前,我想了解这一点。

附录

我在Perl 5.12.0 delta中看到以下内容:


对哈希的弱引用可能会泄漏。这正在影响DBI [RT#56908]。


这可能最终适用于我完整的perl脚本,而不适用于此hello world程序,但是这使我认为我应该经历将非Perl最新版本安装为非root的痛苦。

附录2

我安装了activestate perl 5.16.3,该问题以及我实际脚本的问题仍然存在。

我怀疑在这个hello world程序的情况下,我必须使用/解释valgrind的方式不正确,但是我不知道在哪里。

更新1
达西姆的回答确实有所作为。当我在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)


这是一个很大的差异。我自己的脚本仍然存在内存泄漏问题,但是至少现在这个世界程序对于valgrind似乎很明智。

这整件事虽然引出了一个问题,如果在程序退出之前没有释放任何内存,那么用Scalar::Util停止硬循环引用的意义何在,而禁止使用这个有些深奥的Perl::Destruct::Level模块?

最佳答案

泄漏是故意的。 vincent in #p5p评论:


除非设置PERL_DESTRUCT_LEVEL,否则实际上不会释放已分配的内存,因为让操作系统处理该内存更快。 PERL_DESTRUCT_LEVEL仅可用于调试版本或通过使用perl中的Perl::Destruct::Level

09-04 19:46
查看更多