14

我正在编写一个使用 ARC 的应用程序,目前似乎有一些内存泄漏。谷歌搜索我发现了一些关于如何使用 Inspector 的提示。在那里我可以看到一些类的实例的大量分配,我还可以看到一些关于如何分配对象以及如何更改保留计数的调用堆栈。

但似乎我看不到完整的调用堆栈,所以我不知道最终谁拥有该对象。在我看来,这个所有者以某种方式没有释放对象(或拥有可疑对象的对象)。

任何人都可以给我一个关于找到分配对象的所有者的提示吗?

另请注意,对象未标记为“泄漏”,而是已分配。对我来说,随着不断分配新对象,对象似乎被泄露了。

任何有关如何最好地进行并找到可疑泄漏的进一步帮助表示赞赏。

4

1 回答 1

51
  1. 就谁“拥有”一个对象的学术问题而言,这只是维护strong对该对象的引用的人。

  2. 在您的应用程序中查找泄漏方面,您可以在分析应用程序时使用 Instruments 中的“泄漏”工具(在 Xcode 的“产品”菜单上选择“配置文件”)。

  3. 但是,如果它没有出现在“泄漏”中,那么您似乎必须确定它是否是一个强引用循环(以前称为保留循环),一些简单的逻辑错误(例如视图控制器中的一些循环引用,缓存大型对象等)或一些与核心基础相关的问题(ARC 不承担所有权,除非您小心使用CFBridgingRelease()or __bridge_transfer)。

  4. 在使用 Instruments 查找分配源方面,对我帮助最大的两个技巧是:

    • 用鼠标单击拖动(在 Xcode 6 之前的版本中,您必须在option执行此操作时按住键)以突出显示时间线的一部分,以识别您要检查的内容。您可能希望专注于分配中的一个高峰。例如,我在我的分配中发现了一个凸起并突出显示它(这是一个非常简单的示例,我在其中创建了一个巨大的数组viewDidLoad,但希望它能给你这个想法):

    在此处输入图像描述

    • 当您通过调用树进行检查时,选择“隐藏系统库”通常很有用,以专注于您的代码。如果您双击 Instruments 中的方法名称(在我的示例中,此处为viewDidLoad),Instruments 将显示您正在执行分配的代码:

    在此处输入图像描述

    然后,您可以双击相关的方法列表,它将带您精确到执行分配的代码。

    在此处输入图像描述

虽然这并不能表明您发生了泄漏(即强引用循环的位置或您未能释放它的位置),但这种分析通常可以帮助您追踪泄漏对象的实例化位置,这是第一个跟踪问题的步骤。


如果你真的必须弄清楚谁“拥有”一个对象(即对象的强引用(或保留)发生在哪里),Xcode 8 有一个新的对象图功能。因此,调试应用程序,然后点击调试栏中的“调试内存图”图标(下方红色圆圈)。完成此操作后,您可以在左侧选择一个对象,然后您可以看到显示该对象所有权声明的对象图:

在此处输入图像描述

上面说明了选择的图像具有强引用UIImageView,它被呈现在其中,而且 ViewController 也保持强引用。

在早期的 Xcode 版本中,配置应用程序以通过 Instruments 运行它并选择“记录引用计数”选项。在 Xcode 6 中,它位于最右侧面板的“记录设置”选项卡上:

在此处输入图像描述

在 Xcode 5 及更早版本中,您必须单击一世“分配”工具旁边的信息按钮才能看到此“记录引用计数”选项:

在此处输入图像描述

无论如何,您可以转到分配摘要,深入了解一些未释放的对象,(通过箭在分配工具中查看和对象时单击对象地址旁边的右箭头),然后您将看到相关对象的保留和释放列表,如上所示。但只有在分析应用程序之前选择“记录引用计数”时才会捕获此信息。

习惯这种方式跟踪保留计数需要一段时间,但如果您绝对需要知道强引用是在哪里建立的,“记录引用计数”选项可以帮助您。

于 2012-12-31T18:40:26.490 回答