我知道这个问题涉及到实现的特定领域,但在这一点上,Rakudo/MoarVM的特定答案也会对我有所帮助。
我正在开发一些NativeCall模块,想知道如何调试内存泄漏。一些内存是在C库中处理的,我在那里有一个很好的处理。我知道这个领域是我的责任,在那里MoarVM无能为力。我可以在MoarVM域中做些什么?检查悬空对象、循环引用等的最佳方法是什么?
有没有办法在一系列操作的结尾,我认为我的所有Perl对象都超出了作用域,不能说“运行垃圾收集并告诉我剩余的内容”?
我可以运行一些Rakudo/NQP/MoarVM特定的代码来帮助我吗?这并不是要在生产环境中发布,只是为了在我开发时进行测试/诊断。
Garbage Collection in MoarVM给出了一个诱人的概述,但没有足够的信息让我对它做任何事情。
发布于 2018-02-10 02:14:55
首先,虽然在这种情况下,C端内存泄漏不是您的问题,但值得知道的是,Rakudo安装了一个在valgrind下运行程序的perl6-valgrind-m。在编写本机库绑定时,我已经多次使用它来找出段错误和泄漏。
为了查看由MoarVM管理的对象,可以让VM转储堆快照。它们是在每次GC运行后拍摄的,并强制执行额外的GC运行,并在程序结束时拍摄最终快照。要记录快照,请使用--profile=heap运行。然后,可以将输出文件提供给moar-ha,可以使用zef install App::MoarVM::HeapAnalyzer安装它(它是用Perl6实现的,如果您希望以某种方式对其进行扩展以帮助您解决问题,那么可能值得了解它)。
如果您知道可能泄漏的是哪种类型的对象,那么使用find命令搜索这种类型的对象可能会很有用。然后有一个path命令,它显示了该对象是如何保持活动的。查看不同堆快照之间的对象计数也很有用,以了解哪些对象的使用量在增加。不幸的是,目前还没有快照比较功能。
需要注意的一点是,快照包括在VM上运行的所有内容。这意味着Perl 6编译器将在内存中,以及来自语言内置的一堆对象。(开发该工具是为了帮助跟踪编译器和内置中的托管泄漏,因此这被认为是一个特性。:-)但是,将来可能会有某种过滤。)
最后,您提到了循环引用。这些在Perl6中不是问题,因为GC是通过跟踪完成的,而不是引用计数。
https://stackoverflow.com/questions/48707870
复制相似问题