内存泄漏追踪
内存泄漏是我们关注的主要领域之一。由于普通用户只有在内存使用量不断增长时才会注意到它们,因此我们收到的相关 Bug 报告数量不如预期。这里有一些关于如何追查这些内存泄漏的信息。OS X 开发者工具包含一个非常有用的内存泄漏检测程序。以下是其使用方法:
- 获取一个全新的 WebKit 构建,最好是 Debug 构建,因为这会关闭 WebKit 中各种自定义内存分配器。
- 将 MallocStackLogging 环境变量设置为 YES(在 bash 中,使用
export MallocStackLogging=YES
;在 tcsh 中,使用setenv MallocStackLogging YES
)。 - 使用
run-safari
运行 Safari。 - 浏览一段时间。
- 从命令行运行
leaks Safari
。
此时,如果你发现了内存泄漏,leaks 程序会告诉你数量,并提供每个泄漏的堆栈跟踪。你可以在Bugzilla提交报告,附上你重现泄漏的步骤描述。在标题开头加上“LEAK:”,以便于查找。
如果你想撰写一份更好的 Bug 报告,可以尝试通过遵循特定的步骤来重现泄漏,并将其包含在 Bug 报告中。你还可以查看泄漏报告中的回溯信息,看看是否能消除重复项。为每个独特的泄漏提交单独的 Bug 报告,并将不同站点上的重复泄漏合并起来会很有用。此外,请查阅我们关于提交 Bug 的通用文档。
标准测试中的内存泄漏
我们有两种方法可以自动记录在我们的标准 WebKit 测试中遇到的泄漏的堆栈跟踪。这非常有用,因为 WebKit 测试涵盖了许多在短暂浏览会话中可能不会遇到的不寻常情况。随着我们继续添加 WebKit 测试,这将继续在代码的更多角落测试泄漏。
- (快速) 要获取涵盖所有 WebKit 测试的单个泄漏报告,请使用
run-webkit-tests --leaks
。你还可以传递特定的目录或特定的测试,以获取仅涵盖测试层次结构部分内容的泄漏报告。例如,run-webkit-tests --leaks dom/html/level1
。 - (慢速) 要为每个测试获取单独的泄漏报告,请使用
run-webkit-tests --leaks --singly
。同样,你可以传递一个特定目录,仅在测试层次结构的该部分上运行。此选项速度慢得多,但对于查明泄漏非常有帮助。
修复内存泄漏
修复内存泄漏有点像一门黑魔法。泄漏检查器会告诉你泄漏的内存是在哪里分配的,但不会告诉你为什么它从未被释放。有时,通过代码检查会很明显地发现没有与特定分配匹配的释放调用。其他时候,事情会变得更棘手——尤其是在涉及引用计数(refcounting)时。在这种情况下,你知道某些代码在没有释放的情况下进行了引用(ref),但很难确定是哪段代码。
这里有一个在这些情况下通常很有用的技巧。在gdb
中启动应用程序。在适当的引用(ref)和取消引用(deref)方法上设置断点。然后,使用 gdb 的commands
功能为这些断点设置bt 10; cont
命令。你将获得每个引用和取消引用操作的 10 帧回溯信息,这通常足以找到那个不配对的操作。
消灭所有内存泄漏
如果你想帮助查找和修复内存泄漏,并且需要更多建议,请联系我们。祝你追踪愉快。