常见的 Perl 内存/引用泄漏模式? [英] Common Perl memory/reference leak patterns?

查看:26
本文介绍了常见的 Perl 内存/引用泄漏模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找 Perl 代码库中的几个潜在内存泄漏问题,我想了解有关 Perl 中内存(错误)管理的常见陷阱.

I'm chasing a couple of potential memory leaks in a Perl code base and I'd like to know about common pitfalls with regards to memory (mis-)management in Perl.

您在 Perl 代码中观察到的常见泄漏模式有哪些?

What are common leak patterns you have observed in Perl code?

推荐答案

循环引用是迄今为止最常见的泄漏的典型原因.

Circular references are by far the most commonthe canonical cause of leaks.

sub leak {
    my ($foo, $bar);
    $foo = $bar;
    $bar = $foo;
}

Perl 使用引用计数垃圾收集.这意味着 perl 会记录在给定时间存在哪些指向任何变量的指针.如果变量超出范围并且计数为 0,则清除该变量.

Perl uses reference counting garbage collection. This means that perl keeps a count of what pointers to any variable exist at a given time. If the variable goes out of scope and the count is 0, the variable is cleared.

在上面的示例代码中,$foo$bar 永远不会被收集,并且在每次调用 leak() 后都会保留一个副本因为两个变量的引用计数都是 1.

In the example code above, $foo and $bar are never collected and a copy will persist after every invocation of leak() because both variables have a reference count of 1.

防止此问题的最简单方法是使用弱引用.弱引用是您访问数据时遵循的引用,但不计入垃圾回收.

The easiest way to prevent this issue is to use weak references. Weak references are references that you follow to access data, but do not count for garbage collection.

use Scalar::Util qw(weaken);

sub dont_leak {
    my ($foo, $bar);
    $foo = $bar;
    $bar = $foo;
    weaken $bar;
}

dont_leak()中,$foo的引用计数为0,$bar的引用计数为1.当我们离开时子程序的作用域 $foo 被返回到池中,并且它对 $bar 的引用被清除.这会将 $bar 上的引用计数降至 0,这意味着 $bar 也可以返回到池中.

In dont_leak(), $foo has a reference count of 0, $bar has a ref count of 1. When we leave the scope of the subroutine, $foo is returned to the pool, and its reference to $bar is cleared. This drops the ref count on $bar to 0, which means that $bar can also return to the pool.

更新:Brain d foy 问我是否有任何数据来支持我的断言,即循环引用很常见.不,我没有任何统计数据表明循环引用很常见.它们是 perl 内存泄漏最常被谈论和记录最好的形式.

Update: brain d foy asked if I have any data to back up my assertion that circular references are common. No, I don't have any statistics to show that circular references are common. They are the most commonly talked about and best documented form of perl memory leaks.

我的经验是它们确实会发生.以下是我在使用 Perl 十多年来所看到的内存泄漏的简要概述.

My experience is that they do happen. Here's a quick rundown on the memory leaks I have seen over a decade of working with Perl.

我遇到了 pTk 应用程序泄漏的问题.我能够证明的一些泄漏是由于 Tk 传递窗口引用时出现的循环引用.我还看到了 pTk 泄漏,其原因我永远无法追查.

I've had problems with pTk apps developing leaks. Some leaks I was able to prove were due to circular references that cropped up when Tk passes window references around. I've also seen pTk leaks whose cause I could never track down.

我看到人们误解了 weak 并意外地以循环引用结束.

I've seen the people misunderstand weaken and wind up with circular references by accident.

我看到过当太多考虑不周的物体匆忙扔在一起时会出现无意的循环.

I've seen unintentional cycles crop up when too many poorly thought out objects get thrown together in a hurry.

有一次,我发现内存泄漏来自 XS 模块,该模块正在创建大而深的数据结构.我永远无法获得比整个程序还小的可重现的测试用例.但是当我用另一个序列化器替换模块时,泄漏就消失了.所以我知道这些泄漏来自 XS.

On one occasion I found memory leaks that came from an XS module that was creating large, deep data structures. I was never able to get a reproducible test case that was smaller than the whole program. But when I replaced the module with another serializer, the leaks went away. So I know those leaks came from the XS.

因此,根据我的经验,周期是泄漏的主要来源.

So, in my experience cycles are a major source of leaks.

幸运的是,有一个模块可以提供帮助追踪他们.

Fortunately, there is a module to help track them down.

至于从未清理过的大型全球结构是否构成泄漏",我同意布赖恩的看法.它们像泄漏一样嘎嘎作响(由于错误,我们的进程内存使用量不断增加),因此它们是泄漏.即便如此,我不记得在野外见过这个特定的问题.

As to whether big global structures that never get cleaned up constitute "leaks", I agree with brian. They quack like leaks (we have ever-growing process memory usage due to a bug), so they are leaks. Even so, I don't recall ever seeing this particular problem in the wild.

根据我在巨石阵网站上看到的内容,我猜 Brian 看到了很多来自他正在为其培训或实施治疗奇迹的人的病态代码.所以他的样本集很容易比我的大得多,而且种类繁多,但它有自己的选择偏差.

Based on what I see on Stonehenge's site, I guess brian sees a lot of sick code from people he is training or preforming curative miracles for. So his sample set is easily much bigger and varied than mine, but it has its own selection bias.

最常见的泄漏原因是什么?我认为我们永远不会真正知道.但我们都同意,循环引用和全局数据垃圾场是需要尽可能消除的反模式,并在少数有意义的情况下小心谨慎地处理.

Which cause of leaks is most common? I don't think we'll ever really know. But we can all agree that circular references and global data junkyards are anti-patterns that need to be eliminated where possible, and handled with care and caution in the few cases where they make sense.

这篇关于常见的 Perl 内存/引用泄漏模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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