简体   繁体   English

找到Perl内存泄漏

[英]Finding a Perl memory leak

SOLVED see Edit 2 已解决,请参阅编辑2

Hello, 你好,

I've been writing a Perl program to handle automatic upgrading of local (proprietary) programs (for the company I work for). 我一直在编写一个Perl程序来处理本地(专有)程序的自动升级(对于我工作的公司)。

Basically, it runs via cron, and unfortunately has a memory leak (or something similar). 基本上,它通过cron运行,不幸的是有内存泄漏(或类似的东西)。 The problem is that the leak only happens when I'm not looking (aka when run via cron, not via command line). 问题是泄漏只发生在我不看的时候(也就是说当通过cron运行时,而不是通过命令行)。

My code does not contain any circular (or other) references, so the commonly cited tools will not help me ( Devel::Cycle , Devel::Peek ). 我的代码不包含任何循环(或其他)引用,因此常用的工具对我Devel::CycleDevel::CycleDevel::Peek )。

How would I go about figuring out what is using so much memory that the kernel kills it ? 我怎样才能找出内核杀死内存的内存是多少

Basically, the code SFTPs into a server (using ```sftp...`` `), calls OpenSSL to verify the file, and then SFTPs more if more files are needed, and installs them (untars them). 基本上,代码SFTP进入服务器(使用```sftp ...```),调用OpenSSL来验证文件,然后在需要更多文件时更多SFTP并安装它们(解压它们)。

I have seen delays (~15 sec) before the first SFTP session, but it has never used so much memory as to be killed (in my presence). 在第一次SFTP会议之前我已经看到了延迟(约15秒),但它从来没有使用太多的内存来杀死(在我面前)。

If I can't sort this out, I'll need to re-write in a different language, and that will take precious time. 如果我不能解决这个问题,我需要用不同的语言重写,这将花费宝贵的时间。

Edit: The following message is printed out by the kernel which led me to believe it was a memory leak: 编辑:内核打印出以下消息,这使我相信它是内存泄漏:

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

I don't believe it is an issue with cron because of the stalling (for ~15 sec, sometimes) when running it via the command-line. 我不相信这是cron的问题,因为在通过命令行运行它时会停止(有时约为15秒)。 Also, there are no environmental variables used (at least by what I've written, maybe underlying things do?) 此外,没有使用环境变量(至少通过我所写的内容,可能是潜在的事情吗?)

Edit 2: I found the issue myself, with help from the below comment by mobrule (in response to this question). 编辑2:我自己找到了这个问题,在mobrule的下面评论的帮助下(回答这个问题)。 It turns out that the script was called from a crontab of a user (non-root) just once a day and that (non-root privs) caused a special infinite loop situation. 事实证明,脚本每天只从用户的crontab(非root用户)调用一次,并且(非root权限)导致特殊的无限循环情况。

Sorry guys, I feel kinda stupid for not finding this before, but thanks. 对不起伙计们,我觉得以前没有找到这个有点傻,但谢谢。

mobrule, if you submit your comment as an answer, I will accept it as it lead to me finding the problem. mobrule,如果你提交你的评论作为答案,我会接受它,因为它导致我发现问题。

End Edits 结束编辑

Thanks, Brian 谢谢,Brian

PS I may be able to post small snippets of code, but not the whole thing due to company policy. PS我可以发布小代码片段,但不是由于公司政策而发布的全部内容。

You could try using Devel::Size to profile some of your objects. 您可以尝试使用Devel :: Size来分析您的一些对象。 eg in the main:: scope (the .pl file itself), do something like this: 例如在main:: scope(.pl文件本身)中,执行以下操作:

use Devel::Size qw(total_size);

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

Compare the actual size used to what you think is a reasonable value for each object. 将实际使用的大小与您认为每个对象的合理值进行比较。 Something suspicious might pop out immediately (eg a cache that is massively bloated beyond anything that sounds reasonable). 可能会立即弹出一些可疑的东西(例如,一个听起来很合理的任何东西都会大量膨胀)。

Other things to try: 其他尝试:

  • Eliminate bits of functionality one at a time to see if suddenly things get a lot better; 一次消除一些功能,看看突然事情是否变得更好; I'd start with the use of any external libraries 我首先使用任何外部库
  • Is the bad behaviour localized to just one particular machine, or one particular operating system? 不良行为是仅仅局限于一台特定的机器还是一个特定的操作系统? Move the program to other systems to see how its behaviour changes. 将程序移动到其他系统以查看其行为如何变化。
  • (In a separate installation) try upgrading to the latest Perl (5.10.1), and also upgrade all your CPAN modules (在单独的安装中)尝试升级到最新的Perl(5.10.1),并升级所有CPAN模块

If it is run by cron, that shouldn't it die after iteration? 如果它是由cron运行的,那迭代后不应该死掉吗? If that is the case, hard for me to see how a memory leak would be a big deal... 如果是这种情况,我很难看到内存泄漏将是一个大问题...

Are you sure it is the script itself, and not the child processes that are using the memory? 您确定它是脚本本身,而不是使用内存的子进程吗? Perhaps it ends up creating a real lot of ssh sessions , instead of doing a bunch of stuff in one session? 也许它最终会创建一个真正的ssh会话,而不是在一个会话中做一堆东西?

How do you know that it's a memory leak? 你怎么知道这是内存泄漏? I can think of many other reasons why the OS would kill a program. 我可以想到操作系统会杀死一个程序的许多其他原因。

The first question I would ask is "Does this program always work correctly from the command line?". 我要问的第一个问题是“这个程序是否始终在命令行中正常工作?”。 If the answer is "No" then I'd fix these issues first. 如果答案是“否”,那么我先解决这些问题。

On the other hand if the answer is "Yes", I would investigate all the differences between having the program executed under cron and from the command line to find out why it is misbehaving. 另一方面,如果答案为“是”,我将研究在cron和命令行下执行程序之间的所有区别,以找出它为什么行为不端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM