使用仪器查找内存泄漏
Using instruments to find memory leaks
我已经尝试阅读互联网上几乎所有像样的教程,但仍然无法理解这里到底发生了什么:
我有 "Hide System Libraries" 和 "Invert the call tree",但我不明白如何找到导致此泄漏的实际代码。任何提示表示赞赏。可能是我遗漏了一些明显的东西。我得到了数百个泄漏,但是我在闭包中使用 weak
,我没有 类 相互引用等。但看起来我缺少一些基本的东西。
内存泄漏可能很难追踪。这可能是一个耗时的过程,因此请做好准备。最后,调试内存泄漏通常需要大量的反复试验。 "Memory Leaks" 仪器过去实际上只为我检测到一次泄漏。我总是不得不使用 "Allocations" 仪器自己追踪它们。
过去对我有帮助的一件事是从尝试弄清楚实际泄漏的对象开始。单击分配工具("Leak Checks" 上方的行)。现在尝试按释放的对象数或使用的内存量排序。查看是否有任何计数为 0 的对象在不应停留时被释放。查看是否存在占用异常内存量的对象类型。
内存泄漏总是由于开发人员在内存管理方面的失误。 Foundation 和 UIKit 中的一些较低级别的私有 API 中存在一些小的内存泄漏。在那些较低的级别,他们要处理更多的手动内存管理,因此更容易犯小错误。你真的无能为力,但它们相对罕见。
如果您的应用程序运行良好,您可能不需要担心修复这些问题。你想在这里做一些成本效益分析。如果这不影响性能或稳定性,那么现在花在修复这些问题上的时间投资是否值得它为您和您的用户带来的小好处?
然而,内存泄漏累积起来毫无意义,因此如果用户长时间打开您的应用程序,如果您随着时间的推移继续泄漏更多对象,泄漏的内存量最终将成为一个问题。有时应用程序会崩溃,用户将不得不重新打开。但是,如果您的内存泄漏足够小,除非应用程序已打开 HOURS,否则这不会成为问题,那么它真的是一个大问题吗?这始终是您的判断。
您的屏幕截图中显示的问题是 Instruments 无法找到您应用的调试符号。 Instruments 显示内存地址而不是函数名称。在没有函数名的情况下,您将无法在 Instruments 中找到内存泄漏的来源,即使您反转调用树并隐藏系统库也是如此。
确保您的项目正在生成调试符号。检查生成调试符号构建设置是否设置为是。如果您的项目正在生成调试符号,Instruments 可能无法找到包含调试符号的 dSYM 文件。在 Instruments 中选择 Instrument > Call Tree > Locate dSYM。 dSYM 通常与发布版本的应用程序包位于同一目录中。以下文章包含更多信息:
我已经尝试阅读互联网上几乎所有像样的教程,但仍然无法理解这里到底发生了什么:
我有 "Hide System Libraries" 和 "Invert the call tree",但我不明白如何找到导致此泄漏的实际代码。任何提示表示赞赏。可能是我遗漏了一些明显的东西。我得到了数百个泄漏,但是我在闭包中使用 weak
,我没有 类 相互引用等。但看起来我缺少一些基本的东西。
内存泄漏可能很难追踪。这可能是一个耗时的过程,因此请做好准备。最后,调试内存泄漏通常需要大量的反复试验。 "Memory Leaks" 仪器过去实际上只为我检测到一次泄漏。我总是不得不使用 "Allocations" 仪器自己追踪它们。
过去对我有帮助的一件事是从尝试弄清楚实际泄漏的对象开始。单击分配工具("Leak Checks" 上方的行)。现在尝试按释放的对象数或使用的内存量排序。查看是否有任何计数为 0 的对象在不应停留时被释放。查看是否存在占用异常内存量的对象类型。
内存泄漏总是由于开发人员在内存管理方面的失误。 Foundation 和 UIKit 中的一些较低级别的私有 API 中存在一些小的内存泄漏。在那些较低的级别,他们要处理更多的手动内存管理,因此更容易犯小错误。你真的无能为力,但它们相对罕见。
如果您的应用程序运行良好,您可能不需要担心修复这些问题。你想在这里做一些成本效益分析。如果这不影响性能或稳定性,那么现在花在修复这些问题上的时间投资是否值得它为您和您的用户带来的小好处?
然而,内存泄漏累积起来毫无意义,因此如果用户长时间打开您的应用程序,如果您随着时间的推移继续泄漏更多对象,泄漏的内存量最终将成为一个问题。有时应用程序会崩溃,用户将不得不重新打开。但是,如果您的内存泄漏足够小,除非应用程序已打开 HOURS,否则这不会成为问题,那么它真的是一个大问题吗?这始终是您的判断。
您的屏幕截图中显示的问题是 Instruments 无法找到您应用的调试符号。 Instruments 显示内存地址而不是函数名称。在没有函数名的情况下,您将无法在 Instruments 中找到内存泄漏的来源,即使您反转调用树并隐藏系统库也是如此。
确保您的项目正在生成调试符号。检查生成调试符号构建设置是否设置为是。如果您的项目正在生成调试符号,Instruments 可能无法找到包含调试符号的 dSYM 文件。在 Instruments 中选择 Instrument > Call Tree > Locate dSYM。 dSYM 通常与发布版本的应用程序包位于同一目录中。以下文章包含更多信息: