10

我知道这个问题接近于实现特定的领域,但在这一点上,Rakudo/MoarVM 的特定答案也会对我有所帮助。

我正在研究一些 NativeCall 模块,并且想知道如何调试内存泄漏。一些内存是在 C 库中处理的,我在那里处理得很好。我知道域是我的责任,MoarVM 在那里无能为力。我可以在 MoarVM 域中做什么?检查悬空对象、循环引用等的最佳方法是什么?

有没有办法在一系列操作结束时,我认为我所有的 Perl 对象都超出了“运行垃圾收集并告诉我剩下的事情”的范围?

我可以运行一些 Rakudo/NQP/MoarVM 特定代码来帮助我吗?这不是在生产中发布,只是为了在我开发时进行测试/诊断。

MoarVM 中的垃圾收集提供了一个诱人的概述,但没有足够的信息让我用它做任何事情。

4

1 回答 1

11

首先,虽然在这种情况下 C 端内存泄漏不是您的问题,但值得知道 Rakudo 安装了一个perl6-valgrind-m在 valgrind 下运行程序的程序。在编写本机库绑定时,我已经多次使用它来找出段错误和泄漏。

为了查看 MoarVM 管理的对象,可以让 VM 转储堆快照。它们在每次 GC 运行后拍摄,并强制执行额外的 GC 运行,并在程序结束时拍摄最终快照。要记录快照,请使用--profile=heap. 然后可以将输出文件提供给moar-ha,可以使用它进行安装zef install App::MoarVM::HeapAnalyzer(它在 Perl 6 中实现,如果您希望以某种方式扩展它以帮助您解决问题,这可能值得了解)。

如果您对可能泄漏的对象有任何想法,那么使用该find命令搜索该类型的对象会很有用。然后有一个path命令显示该对象如何保持活动状态。查看不同堆快照之间的对象计数也很有用,以了解使用中的增长情况。不幸的是,还没有快照差异功能。

需要注意的一点是,快照包括在 VM 上运行的所有内容。这意味着 Perl 6 编译器将在内存中,以及来自语言内置程序的一堆对象。(开发该工具是为了帮助追踪编译器和内置程序中的托管泄漏,因此这被认为是一项功能。:-) 但是,将来某种过滤可能是可行的。)

最后,您提到了循环引用。这些在 Perl 6 中不是问题,因为 GC 是通过跟踪完成的,而不是引用计数。

于 2018-02-09T18:14:54.817 回答