您当前的位置: 首页 >  xcode

使用Xcode的memory graph查找内存泄漏

发布时间:2021-03-01 20:51:30 ,浏览量:0

由donnywals于2019年12月9日发布 代码无法充分发挥功能的原因很多。 在一篇文章中,我向您展示了如何使用Time Profiler来测量代码中每种方法所花费的时间,以及如何分析结果。 尽管可以使用这些工具发现,分析和修复许多与性能相关的问题,但通常必须对调试的内存使用情况进行一些稍有不同的调试。 特别是与内存泄漏有关。

在今天的帖子中,我将向您展示如何使用Xcode中的Memory Graph工具来分析应用程序内存中保留的对象,以及如何使用此工具发现内存泄漏。 今天,我将特别关注保留周期。

Activating the Memory Graph

使用Xcode运行应用程序时,可以单击位于代码和控制台之间的内存调试器图标,如果未打开控制台,则可以单击Xcode窗口底部的内存:

Memory debugger icon

当您单击此图标时,Xcode将为您的应用程序的内存图以及每个对象与其他对象之间的关系拍摄快照。 您的应用程序的执行将被暂停,Xcode将向您显示当前内存中的所有对象。 请注意,这可能需要一些时间,具体取决于应用程序的大小。

Example memory graph

Xcode在左侧的侧栏中,显示了已发现的所有对象的完整列表。 当您在侧栏中选择一个对象时,中间部分将显示您选择的对象及其与其他对象的关系。 有时它是一个大图,如屏幕截图所示。 其他时候,它是一个只有几个对象的较小图形。

如果Xcode发现可能是内存泄漏或保留周期的关系,它将在边栏中的对象后面添加一个带有问号的紫色方块。 在您刚刚看到的屏幕截图中,紫色方块的位置非常明显。 如果它们更隐藏,或者您只想过滤内存泄漏,则可以使用侧边栏底部的过滤器菜单进行过滤,如以下屏幕截图所示:

Filtered view

上面的屏幕截图显示了两个不同对象的实例被保留在内存中,而Xcode认为不应这样做。 当您单击其中之一时,问题立即变得可见。

Retain cycle image

在此示例中,DataProvider和DetailPage指向彼此。 保留周期的经典示例。 让我们看看这种情况是如何发生的,以及您可以采取的解决措施。

了解retain cycles如何发生以及如何修复它们

在iOS中,当没有其他对象强烈引用它们时,会将它们从内存中删除。您在应用中创建的对象的每个实例都有一个保留计数。每当您将对对象的引用传递到代码中的其他位置时,其保留计数都会增加,因为现在又有一个对象指向该对象在内存中的位置。

保留计数的这一原则主要适用于类。因为当您在代码中传递类的实例时,实际上是在传递内存引用,这意味着多个对象指向同一内存地址。当传递值类型时,传递值时将复制该值。这意味着值类型的保留计数通常始终为1;指向一个值类型的内存地址的对象永远不会超过一个。

为了将对象从内存中删除,其引用计数必须为零;否则,引用计数必须为零。任何对象都不应引用内存中的该地址。当两个对象彼此保持引用时(在使用委托时通常是这种情况),这两个对象的引用计数可能永远不会达到零,因为它们彼此保持引用。请注意,我在本节的开头提到了一个强大的参考资料,我是故意这样做的。强引用造成的内存泄露问题,还可以通过Leaks工具来检测,具体步骤参考《iOS开发中的神兵利器》第10章的第23节:使用instruments Leaks工具检测内存泄露。

如果我们有很强的参考力,那么肯定存在弱参考权之类的事情吗?有!

弱引用是对引用类型实例的引用,这些引用类型不会增加引用所指向的对象的引用计数。这里适用的原理与在闭包中使用弱自我完全相同。通过使对象的委托属性变弱,委托及其所有者就不会彼此保持活动状态,并且可以释放两个对象。在示例中,我们正在研究这意味着我们需要更改以下代码:

class DataProvider {
  var delegate: DataDelegate?

  // rest of the code
}

分为以下内容:

class DataProvider {
  weak var delegate: DataDelegate?

  // rest of the code
}

为此,必须将DataDelegate限制为一个类,您可以通过在协议声明中添加:AnyObject来做到这一点。 例如:

protocol DataDelegate: AnyObject {
  // requirements
}

当您再次运行该应用程序并使用内存图查找保留周期时,您会注意到不再有紫色方块,并且内存图看起来完全符合您的期望。

总结

在本文中,我向您展示了可以使用Xcode可视化和浏览应用程序的内存图。 这可以帮助您查找内存泄漏并保留周期。 单击内存中的对象时,可以探索其与其他对象的关系,最终可以跟踪保留周期。 您还了解了什么是保留周期,它们如何发生以及如何打破它们。

译自:https://www.donnywals.com/using-xcodes-memory-graph-to-find-memory-leaks/

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    109966博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0552s