Rakudo Memory/Garbage 收集技巧

Rakudo Memory/Garbage collecting techniques

我知道这个问题涉及具体实施领域,但在这一点上,Rakudo/MoarVM 具体答案也会对我有所帮助。

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

有没有办法在一系列操作结束时,我认为我所有的 Perl 对象都超出范围说 "Run Garbage Collection and tell me about anything left"?

是否有一些 Rakudo/NQP/MoarVM 特定代码可以 运行 帮助我?这不是在生产中发布,只是为了 testing/diagnostics 我正在开发。

Garbage Collection in MoarVM 给出了一个诱人的概述,但没有足够的信息让我用它做任何事情。

首先,虽然在这种情况下 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 是通过跟踪而不是引用计数完成的。