ios 当 Leaks 工具没有显示内存泄漏时,如何调试它们?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30992338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to debug memory leaks when Leaks instrument does not show them?
提问by Rasto
I have an iOS app written in Swift that is leaking memory - in certain situation some objects should be released but they are not. I have learnt about the issue by simply adding deinit
debug messages like this:
我有一个用 Swift 编写的 iOS 应用程序正在泄漏内存 - 在某些情况下,一些对象应该被释放,但它们不是。我通过简单地添加这样的deinit
调试消息来了解这个问题:
deinit {
println("DEINIT: KeysProvider released")
}
So, the deinit message should be present in console after such events that should cause the object to release. However, for some of the objects that should be released, the message is missing. Still, Leaks Developer Tool does not show any leaks. How do I solve such situation?
因此,在应该导致对象释放的此类事件之后,控制台中应该出现 deinit 消息。但是,对于一些应该释放的对象,消息丢失了。尽管如此,Leaks Developer Tool 并未显示任何泄漏。我该如何解决这种情况?
回答by Rob
In Xcode 8, you can click on the "Debug Memory Graph" button, in the debug toolbar (shown at the bottom of the screen):
在 Xcode 8 中,您可以单击调试工具栏中的“调试内存图”按钮(显示在屏幕底部):
Just identify the object in the left panel that you think should have been deallocated, and it will show you the object graph (shown in the main canvas, above). This is very useful in quickly identifying where the strong references were established on the object in question. From here, you can start your research, diagnosing why those strong references were not resolved (e.g. if the object in question has a strong reference from something else that should have been deallocated, look at that object's graph, too, and you may find the issue (e.g. strong reference cycles, repeating timers, etc.).
只需在左侧面板中确定您认为应该已释放的对象,它就会向您显示对象图(显示在上面的主画布中)。这对于快速识别在相关对象上建立强引用的位置非常有用。从这里,你可以开始你的研究,诊断为什么那些强引用没有被解析(例如,如果有问题的对象有来自其他应该被释放的东西的强引用,也看看那个对象的图表,你可能会发现问题(例如强引用周期、重复计时器等)。
Notice, that in the right panel, I'm seeing the call tree. I got that by turning on the "malloc stack" logging option in the scheme settings:
请注意,在右侧面板中,我看到了调用树。我通过打开方案设置中的“malloc 堆栈”日志记录选项来实现这一点:
Anyway, having done that, one can then click on the arrow next to the relevant method call shown in the stack trace in the right panel of the first screen snapshot above, and you can see where that strong reference was originally established:
无论如何,完成后,您可以单击上面第一个屏幕快照右侧面板中堆栈跟踪中显示的相关方法调用旁边的箭头,您可以看到最初建立强引用的位置:
The above memory diagnostic technique (and more) is demonstrated in the latter part of WWDC 2016 Visual Debugging with Xcode.
WWDC 2016 Visual Debugging with Xcode的后半部分演示了上述内存诊断技术(以及更多)。
The traditional Instruments technique (especially useful if using older versions of Xcode) is described below, in my original answer.
下面在我的原始答案中描述了传统的 Instruments 技术(如果使用旧版本的 Xcode,则特别有用)。
I would suggest using Instruments' "Allocations" tool with the "Record Reference Counts" feature:
我建议使用具有“记录引用计数”功能的 Instruments 的“分配”工具:
You can then run the app in Instruments and then search for your class that you know is leaking and drill in by clicking on the arrow:
然后,您可以在 Instruments 中运行该应用程序,然后通过单击箭头搜索您知道正在泄漏的类并深入了解:
You can then drill into the details and look at the stack trace using the "Extended Details" panel on the right:
然后,您可以使用右侧的“扩展详细信息”面板深入了解详细信息并查看堆栈跟踪:
In that "Extended Details" panel, focus on your code in black rather than the system calls in gray. Anyway, from the "Extended Details" panel, you can then drill into your source code, right in Instruments::
在那个“扩展细节”面板中,关注黑色的代码而不是灰色的系统调用。无论如何,从“扩展详细信息”面板中,您可以直接在 Instruments 中深入查看源代码:
For more information and demonstrations in using Instruments to track down memory problems, please refer to:
有关使用 Instruments 跟踪内存问题的更多信息和演示,请参阅:
- WWDC 2013 video Fixing Memory Issues
- WWDC 2012 video iOS App Performance: Memory
- WWDC 2013 视频修复内存问题
- WWDC 2012 视频iOS 应用性能:内存
回答by zaph
Use instruments to check for leaks and memory loss due to retained but not leaked memory. The latter is unused memory that is still pointed to. Use Mark Generation (Heapshot) in the Allocations instrument on Instruments.
使用仪器检查由于保留但未泄漏的内存而导致的泄漏和内存丢失。后者是仍然指向的未使用内存。在 Instruments 的 Allocations 工具中使用 Mark Generation (Heapshot)。
For HowTo use Heapshot to find memory creap, see: bbum blog
有关如何使用 Heapshot 查找内存崩溃的方法,请参阅:bbum 博客
Basically the method is to run Instruments allocate tool, take a heapshot, run an iteration of your code and take another heapshot repeating 3 or 4 times. This will indicate memory that is allocated and not released during the iterations.
基本上,该方法是运行 Instruments 分配工具,进行一次堆快照,运行代码的迭代并进行另一个重复 3 或 4 次的堆快照。这将指示在迭代期间分配和未释放的内存。
To figure out the results disclose to see the individual allocations.
要找出结果,请查看个人分配。
If you need to see where retains, releases and autoreleases occur for an object use instruments:
如果您需要查看对象的保留、释放和自动释放发生的位置,请使用工具:
Run in instruments, in Allocations set "Record reference counts" on (For Xcode 5 and lower you have to stop recording to set the option). Cause the app to run, stop recording, drill down and you will be able to see where all retains, releases and autoreleases occurred.
在仪器中运行,在分配中设置“记录引用计数”(对于 Xcode 5 及更低版本,您必须停止记录以设置选项)。使应用程序运行、停止记录、向下钻取,您将能够看到所有保留、发布和自动发布发生的位置。