2013-06-21 14 views
2

手头的问题是找到内存泄漏。我已经使用Devel :: Refcount来显示应用程序中的哪些对象在内存中不应该保留时。枚举perl解释器中的所有引用

已经提出了三种方法来找到这些结构的难以捉摸的链接。

1 - 也许存在一个数据结构,可以让我得到指向我的对象的符号列表,这将是理想和直接的。

2 - 遍历所有已定义的名称空间中的符号表,查找引用并使用迭代堆栈来确定它的位置。

3 - 插入一个钩子,可以让我记录堆栈位置,当某个引用的链接计数已经改变或改变时,以及持有该链接的符号的地址。我可以使用它来找到哪些符号直接保存我的参考。

这是可能的吗?这种反思是棘手的东西,我可能很了解perl,但我不知道如何去做。我对padwalker的研究看起来好像可能有关键,但并没有出生。你的想法?

+0

请注意,您可以使用内建'内部:: SvREFCNT(%$ self)访问refcount' – ikegami

+0

我有refcount。我希望持有refcount非零的结构的名称空间定义,以及谁将THAT结构的refcount保持为非零等等,直到我找到具有不应该在范围内定义的值的变量。 – Skylos

+0

我相信你有最后的答复。既然您知道哪个对象在泄漏,您可以使用此功能和标准调试来查找泄漏。 – ikegami

回答

-2

你可以尝试遍历:: hash;那就是主要的命名空间,它将符号名称映射到值。该命名空间中任何以::结束的键都是命名空间,可以通过迭代从命名空间获得的值或仅将该命名空间视为散列来迭代。即

>perl -le 'print foreach keys %::' 
version:: 
/
stderr 
_<mro.c 
Tie:: 
utf8:: 
" 
re:: 
CORE:: 
DynaLoader:: 
mro:: 
stdout 
attributes:: 

stdin 
ARGV 
INC 
ENV 
Regexp:: 
UNIVERSAL:: 
$ 
_<perlio.c 
main:: 
_<perlmain.c 
PerlIO:: 
0 
_<universal.c 

@ 
_<xsutils.c 
STDOUT 
IO:: 

_ 
STDERR 
Internals:: 
STDIN 
DB:: 





    >perl -le 'print foreach keys %mro::' 
    get_mro 
    get_linear_isa 
    get_pkg_gen 
    set_mro 
    invalidate_all_method_caches 
    is_universal 
    method_changed_in 
    get_isarev 
+0

这将只列出包变量。大多数变量不是包变量。 – ikegami

+0

这将在任何命名空间中找到任何变量;无论是全球变量还是包变量。词汇变量不在名称空间中,所以我回答的问题部分不适用于此。 –

+2

(“无论是全局还是包变量”是没有意义的,每个包变量都是全局变量,每个全局变量都是包变量。)确切地说,词法和匿名变量不会被发现,并且它们可以很好地保存引用到物体。事实上,它几乎肯定是其中之一。你的回答没有帮助,可能会导致问题得不到应有的答案。 – ikegami

0

Test::LeakTrace怎么样?

#!perl 
use Test::LeakTrace; 

no_leaks_ok { 
    # Suspect code here 
}; 

这将运行该块几次,然后,如果所有的解释增加的Perl值,测试:: LeakTrace认为有内存泄漏。

+0

不幸的是,这似乎告诉我发生了分配的位置(我已经通过应用程序上下文知道了)我想知道谁对先前创建的引用有非弱引用。 – Skylos