泄漏仪器未显示泄漏时如何调试内存泄漏?

我有一个用Swift编写的iOS应用,正在泄漏内存-在某些情况下,应该释放某些对象,但不能释放。 我已经通过简单添加deinit调试消息来了解此问题:

deinit {
    println("DEINIT: KeysProvider released")
}

因此,应该在导致对象释放的事件之后在控制台中出现deinit消息。 但是,对于某些应释放的对象,该消息丢失。 尽管如此,Leaks Developer Tool仍未显示任何泄漏。 我该如何解决这种情况?

2个解决方案
115 votes

在Xcode 8中,您可以单击“调试内存图”按钮,debugmemorygraphbutton在调试工具栏(显示在屏幕底部)中:

debug memory graph

只需在左侧面板中标识您认为应该已重新分配的对象,它就会向您显示对象图(如上图主画布所示)。 这对于快速确定在相关对象上建立强引用的位置非常有用。 从这里,您可以开始研究,诊断为什么无法解析这些强引用(例如,如果所讨论的对象具有本应释放的其他对象的强引用,也请查看该对象的图,您可能会发现 问题(例如强参考周期,重复计时器等)。

注意,在右侧面板中,我看到了调用树。 我是通过在方案设置中打开“ malloc堆栈”日志记录选项来实现的:

malloc stack

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

code

上面的内存诊断技术(以及更多)在WWDC 2016的Xcode可视化调试的后一部分中进行了演示。


在我的原始答案中,下面介绍了传统的Instruments技术(如果使用较旧版本的Xcode尤其有用)。


我建议使用具有“记录引用计数”功能的Instruments的“分配”工具:

record reference counts

然后,您可以在Instruments中运行该应用,然后搜索您知道正在泄漏的课程,并通过单击箭头进行深入研究:

enter image description here

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

extended details

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

your code

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

  • WWDC 2013视频修复内存问题
  • WWDC 2012视频iOS应用性能:内存
Rob answered 2019-11-15T16:17:04Z
2 votes

使用仪器检查由于保留但未泄漏的内存造成的泄漏和内存丢失。 后者是仍指向的未使用的内存。 在“乐器”上的“分配”乐器中使用“标记生成(堆放)”。

有关如何使用Heapshot查找内存蠕变的信息,请参阅:bum博客

基本上,方法是运行Instruments分配工具,进行一次堆快照,运行您的代码迭代并进行另一次重复3或4次的堆快照。 这将指示在迭代期间已分配但未释放的内存。

要弄清楚结果,请公开查看各个分配。

如果需要查看对象的保留,释放和自动释放位置,请使用工具:

在乐器中运行,在分配中设置“记录参考计数”(对于Xcode 5及更低版本,您必须停止记录才能设置该选项)。 使应用程序运行,停止记录,向下钻取,您将能够看到所有保留,发布和自动发布发生的位置。

zaph answered 2019-11-15T16:18:09Z
translate from https://stackoverflow.com:/questions/30992338/how-to-debug-memory-leaks-when-leaks-instrument-does-not-show-them