当Leaks仪器没有显示时,如何调试内存泄漏?

Ras*_*sto 55 memory-leaks memory-management ios automatic-ref-counting swift

我有一个用Swift写的iOS应用程序泄漏内存 - 在某些情况下应该释放一些对象,但事实并非如此.我通过简单地添加如下deinit调试消息来了解这个问题:

deinit {
    println("DEINIT: KeysProvider released")
}
Run Code Online (Sandbox Code Playgroud)

因此,在应该导致对象释放的此类事件之后,deinit消息应该存在于控制台中.但是,对于应该释放的某些对象,消息将丢失.仍然,Leaks Developer Tool没有显示任何泄漏.我该如何解决这种情况?

Rob*_*Rob 116

在Xcode 8中,您可以单击"Debug Memory Graph"按钮, debugmemorygraphbutton 在调试工具栏中(显示在屏幕底部):

调试内存图

只需在左侧面板中标识您认为应该已取消分配的对象,它将显示对象图(显示在上面的主画布中).这对于快速识别在相关对象上建立强引用的位置非常有用.从这里,你可以开始你的研究,诊断为什么那些强引用没有得到解决(例如,如果有问题的对象有一个应该被解除分配的其他东西的强引用,也可以查看该对象的图表,你可能会发现问题(例如强参考周期,重复计时器等).

请注意,在右侧面板中,我看到了调用树.我通过在方案设置中打开"malloc stack"日志记录选项来实现此目的:

malloc堆栈

无论如何,完成后,可以单击上面第一个屏幕快照右侧面板中堆栈跟踪中显示的相关方法调用旁边的箭头,您可以看到最初建立强引用的位置:

码

上面的内存诊断技术(以及更多)在WWDC 2016 Visual Debugging with Xcode的后半部分进行了演示.


传统的仪器技术(在使用旧版Xcode时特别有用)在我的原始答案中描述如下.


我建议使用Instruments的"Allocations"工具和"Record Reference Counts"功能:

记录参考计数

然后,您可以在Instruments中运行该应用程序,然后搜索您知道正在泄漏的类,并通过单击箭头钻取:

在此输入图像描述

然后,您可以使用右侧的"扩展详细信息"面板深入查看详细信息并查看堆栈跟踪:

扩展细节

在"扩展详细信息"面板中,将焦点放在黑色代码而不是灰色系统调用上.无论如何,从"扩展详细信息"面板,您可以直接在Instruments ::中钻取您的源代码::

你的代码

有关使用Instruments跟踪内存问题的更多信息和演示,请参阅:

  • 您可以通过选择"未配对"的保留/释放来缩小范围(请参阅上面第三个快照顶部的按钮),这样您就不会全部**了.但是,在那之后,是的,你可能仍然需要亲自手动完成剩下的工作.它并不完美,但你应该能够很快缩小范围. (2认同)