内存泄漏追踪

内存泄漏是我们关注的主要领域之一。由于普通用户只有在内存使用量不断增长时才会注意到它们,因此我们收到的相关 Bug 报告数量不如预期。这里有一些关于如何追查这些内存泄漏的信息。OS X 开发者工具包含一个非常有用的内存泄漏检测程序。以下是其使用方法:

  1. 获取一个全新的 WebKit 构建,最好是 Debug 构建,因为这会关闭 WebKit 中各种自定义内存分配器。
  2. 将 MallocStackLogging 环境变量设置为 YES(在 bash 中,使用export MallocStackLogging=YES;在 tcsh 中,使用setenv MallocStackLogging YES)。
  3. 使用run-safari运行 Safari。
  4. 浏览一段时间。
  5. 从命令行运行leaks Safari

此时,如果你发现了内存泄漏,leaks 程序会告诉你数量,并提供每个泄漏的堆栈跟踪。你可以在Bugzilla提交报告,附上你重现泄漏的步骤描述。在标题开头加上“LEAK:”,以便于查找。

如果你想撰写一份更好的 Bug 报告,可以尝试通过遵循特定的步骤来重现泄漏,并将其包含在 Bug 报告中。你还可以查看泄漏报告中的回溯信息,看看是否能消除重复项。为每个独特的泄漏提交单独的 Bug 报告,并将不同站点上的重复泄漏合并起来会很有用。此外,请查阅我们关于提交 Bug 的通用文档

标准测试中的内存泄漏

我们有两种方法可以自动记录在我们的标准 WebKit 测试中遇到的泄漏的堆栈跟踪。这非常有用,因为 WebKit 测试涵盖了许多在短暂浏览会话中可能不会遇到的不寻常情况。随着我们继续添加 WebKit 测试,这将继续在代码的更多角落测试泄漏。

  1. (快速) 要获取涵盖所有 WebKit 测试的单个泄漏报告,请使用run-webkit-tests --leaks。你还可以传递特定的目录或特定的测试,以获取仅涵盖测试层次结构部分内容的泄漏报告。例如,run-webkit-tests --leaks dom/html/level1
  2. (慢速) 要为每个测试获取单独的泄漏报告,请使用run-webkit-tests --leaks --singly。同样,你可以传递一个特定目录,仅在测试层次结构的该部分上运行。此选项速度慢得多,但对于查明泄漏非常有帮助。

修复内存泄漏

修复内存泄漏有点像一门黑魔法。泄漏检查器会告诉你泄漏的内存是在哪里分配的,但不会告诉你为什么它从未被释放。有时,通过代码检查会很明显地发现没有与特定分配匹配的释放调用。其他时候,事情会变得更棘手——尤其是在涉及引用计数(refcounting)时。在这种情况下,你知道某些代码在没有释放的情况下进行了引用(ref),但很难确定是哪段代码。

这里有一个在这些情况下通常很有用的技巧。在gdb中启动应用程序。在适当的引用(ref)和取消引用(deref)方法上设置断点。然后,使用 gdb 的commands功能为这些断点设置bt 10; cont命令。你将获得每个引用和取消引用操作的 10 帧回溯信息,这通常足以找到那个不配对的操作。

消灭所有内存泄漏

如果你想帮助查找和修复内存泄漏,并且需要更多建议,请联系我们。祝你追踪愉快。