如何find记忆警告的真正原因,以及如何解决在iOS应用程序

我已经经历了许多相关的内存pipe理,ARC,内存pipe理技术,如autoreleasepool和使用仪器工具来检测哪些代码导致内存警告,但在我的情况下,我无法找出确切的原因。

基本的细节,你必须知道的应用程序:

  1. 我们开发了一个iPad应用程序。 在这种情况下,我们必须在某些情况下使用超过2000个图像,所以当我的应用程序启动时,我们不想显示占位符图像(客户端要求)。因此,我们使用SDWebImage ,将图像存储在磁盘上,晚于我们正在从那里加载图片。

  2. 有如此多的核心animation,我已经表演过,如“Gennie效果”,显示popup等许多其他核心animation。

我们在我们的项目中使用了ARC,我们发现由于内存警告应用程序随机崩溃。

我们使用仪器 “分配”来find脏记忆。

之前我们对日志进行了分析,并将SDWebImage中的图片存储在DISK中,解决了应用程序频繁崩溃的问题,但是由于内存警告,应用程序仍然崩溃。

当我们深入了解时,我们发现“匿名虚拟机”在iPad上任何屏幕切换时都会保持加载状态而不释放内存。

这里是我们的设备上的应用程序分析截图。

在这里输入图像说明

任何人都可以build议提示或编码技术或任何想法,我们可以减less内存负荷和解决内存警告。

任何帮助将不胜感激。 谢谢。

尝试推断它可能会有帮助,它会报告iOS和C代码中的内存泄漏问题。

在Facebook部署一个静态分析器,它被用作移动应用程序开发过程的一部分。 推断重要的错误,如空指针exception,资源泄漏和内存泄漏 – 导致应用程序崩溃或性能下降的问题。

它看起来像你的应用程序中的某个对象没有被释放,可能是由于一个保留周期。 检查所有对委托的引用是弱引用。 同时检查块,并确保一个强烈的自我引用不被捕获在一个块中。 如果对象A保持对对象B的强引用,然后将包含对自我的强引用的块传递给对象B,则两个对象都可能被locking在保留周期中。 使用此语法将弱引用传递给self:

  __weak typeof(self)weakSelf = self; [doSomethingWithBlock:^() { __strong typeof(weakSelf)strongSelf = weakSelf; if (!strongSelf) { return; } [strongSelf doSomething];}]; 

在Swift中这样做:

 someObject.doSomething() { [weak self] in self?.doSomething() } 

或者使用[无主的自我] – 都对自我创造了一个弱的引用,在[weak self]的情况下,self是可选的

为了确保所有的对象都按预期的方式被释放,在你的dealloc / deinit函数中join一个日志语句并检查它们是否真的被调用。

金刚狼

不要说这是你的问题的绝对答案,但可能会提供一些提示来解决问题。

我的情况 :

今天早上,在debugging内存崩溃的时候,就像你在我的一个聊天应用程序中遇到类似的情况一样。 我也使用SDWebImage来caching和加载图像以供后续使用。

初步观察使我相信这是SDWebImage的崩溃。 不久,我意识到,crach是因为一个非常简单的问题。

我从来没有testing过我的viewController的dealloc是否被调用。 在dealloc放置一个断点时,我意识到dealloc从来没有被调用(因为我现在解决的各种原因)。

就像你的情况一样,我的chatViewController虽然没有加载用来加载8-10张图片的图片,但是当我使用全景图片而不是普通图片的时候,图片开始出现。

结论:

  1. 我的viewController有很强的参考UIImageView加载沉重的图像,因为dealloc从来没有要求我的ViewController所有加载的图像从来没有realesed导致内存崩溃。

  2. 当我加载沉重的图像时,我正在执行一些计算来减小图像的大小。 大多数计算涉及使用UIImageJPEGRepresentation从NSData重复创build图像。 重复分配的数据和图像保持器variables添加到应用程序的内存消耗。

  3. 由于我的ViewController涉及到多个API调用,所以我创build了一个单例引用服务类,我用它来传递complionblocks,并在传递给方法的completionblocks中使用self。 哪些实际上有助于ARC引用计数增量,永远不会让我的视图控制器释放。

debugging方法

  1. 正如你已经在你的问题中已经提到,你正在加载你的ViewController的图像,确保viewController得到正确解除分配,并释放由ViewController中存在的所有ImageView加载的所有内存。

  2. 如果你的ViewController的dealloc没有被调用,那么只需要在viewWillAppear中testing(记住不是一个解决scheme)的方式,将所有的imageView的图像属性设置为零,并强制清除加载的内存。

  3. 如果ViewController dealloc没有被调用是罪魁祸首,请尝试find你自己发送自己的地方作为强大的参考。 如果发现尝试使用weak self

我知道这不是你的问题的绝对答案。 只是与你分享我的经验。 希望这将至less给你提示解决你的问题。

在WWDC 2012 Session 242 iOS应用程序性能:内存方面 ,Apple推出了一种使用乐器Allocations模板检测内存问题的方法,从31分钟开始。

1。 堆捕捉射击
苹果build议在拍摄堆的快照之前反复推popup,我更喜欢只推一次。

快照button被命名为“标记生成”
快照按钮

您应该多次拍摄快照。

2。 记忆力增长

如果您的内存在每个快照之间增长,您可以挖掘除第一个之外的其中一个快照。

在这里输入图像说明

通过Persitentsorting对象,你可能已经看到了你的问题ViewController(如果你只是推一下),或者你可以search它。

persitent

现在你可以深入调用树,find并解决问题。

你可以使用这种技术不仅仅是为了推动popupviewControllers,而且滚动tableView,执行databaseSearch和任何其他情况。