找到Perl内存泄漏

时间:2009-11-02 20:30:47

标签: perl memory-leaks

已解决请参阅编辑2

您好,

我一直在编写一个Perl程序来处理本地(专有)程序的自动升级(对于我工作的公司)。

基本上,它通过cron运行,不幸的是内存泄漏(或类似的东西)。问题是泄漏只发生在我不看的时候(也就是说当通过cron运行时,而不是通过命令行运行)。

我的代码不包含任何循环(或其他)引用,因此常用的工具无法帮助我(Devel::CycleDevel::Peek)。

我如何找出使用内核杀死这么多内存的内容?

基本上,代码SFTP进入服务器(使用```sftp ...```),调用OpenSSL来验证文件,然后如果需要更多文件则更多SFTP,并安装它们(解开它们)。

我在第一次SFTP会议之前看到了延迟(约15秒),但它从来没有使用太多的内存来杀死(在我面前)。

如果我不能解决这个问题,我需要用另一种语言重写,这将花费宝贵的时间。

编辑:内核打印出以下消息,这让我相信这是内存泄漏:

[100023.123] Out of memory: kill process 9568 (update.pl) score 325406 or a child
[100023.123] Killed Process 9568 (update.pl)

我不相信这是cron的问题,因为在通过命令行运行它时会停止(有时约为15秒)。此外,没有使用环境变量(至少通过我所写的内容,可能是潜在的事情吗?)

编辑2:我自己发现了这个问题,并得到了mobrule的以下评论的帮助(回答这个问题)。事实证明,脚本每天只从用户的crontab(非root用户)调用一次,并且(非root权限)导致特殊的无限循环情况。

对不起,伙计们,我觉得因为之前没找到这个而感到愚蠢,但谢谢。

mobrule,如果你提交你的评论作为答案,我会接受它,因为它导致我发现问题。

结束修改

谢谢, 布赖恩

P.S。我可能会发布一小段代码,但不是由于公司政策而发布的全部内容。

3 个答案:

答案 0 :(得分:5)

您可以尝试使用Devel::Size配置一些对象。例如在main::范围内(.pl文件本身),执行以下操作:

use Devel::Size qw(total_size);

foreach my $varname (qw(varname1 varname2 ))
{
    print "size used for variable $varname: " . total_size($$varname) . "\n";
}

将实际使用的尺寸与您认为每个对象的合理值进行比较。可能会立即弹出一些可疑的东西(例如,一个听起来很合理的缓存超出任何合理的缓存)。

其他尝试:

  • 一次消除一些功能,看看突然事情是否会变得更好;我首先使用任何外部库
  • 是否将错误行为本地化为一个特定的计算机或一个特定的操作系统?将程序移动到其他系统以查看其行为如何变化。
  • (在单独的安装中)尝试升级到最新的Perl(5.10.1),并升级所有CPAN模块

答案 1 :(得分:1)

如果它是由cron运行的,那迭代后它不应该死掉吗?如果是这种情况,我很难看到内存泄漏将是一件大事......

您确定它是脚本本身,而不是使用内存的子进程吗?也许最终会创建一个真正的ssh会话,而不是在一个会话中做一堆东西?

答案 2 :(得分:1)

你怎么知道这是内存泄漏?我可以想到操作系统会杀死程序的许多其他原因。

我要问的第一个问题是“此程序是否始终在命令行中正常工作?”。如果答案是“否”,那么我先解决这些问题。

另一方面,如果答案是“是”,我会调查在cron和命令行下执行程序之间的所有区别,以找出它为什么行为不端。