17

我正在创建一个应用程序,它是一种画廊 - 它以全屏查看器的形式显示不同的媒体内容。分配工具显示,使用应用程序时 Live Bytes 参数不会增长到超过 40 Mb。同时,在我滑动页面 20-30 次后,该应用程序 100% 被杀死。我检查了 Dirty Memory 参数,发现它比 Live Bytes 大小大 10 倍。大部分脏内存消耗了 Image IO:

截屏

编辑,另一个屏幕截图:

截屏

上面的分配峰值是切换视频/图像媒体内容。问题是脏内存几乎呈线性增长,我需要以某种方式释放它。

现在关于应用程序设计。应用程序屏幕有一个水平滚动视图。滚动视图包含包含多个图像的视频或拼贴对象。为了节省内存,一次只创建三个页面 - 当前页面和左侧/右侧页面。所以页面总是在滑动滚动视图时创建和删除。

[UIImage imageWithContentOfFile: path]我使用方法加载的所有图像。Collage 对象将 UIImage 实例存储在 imagesArray 中。在 dealloc 方法中,imagesArray 属性被清除。

所以,问题:

  • 它是一种系统错误吗[UIImage imageWithContentOfFile?]
  • 是图像 IO 缓存吗?
  • 我可以清除它吗?
4

2 回答 2

22

把这个放在这里太大了,无法评论,只是一些想法:

1)错误地保留对象的一种方法是让视图中的对象隐藏但未从其父视图中删除(因此保持保留)

2)如果您在任何线程上对 UIImageView 等进行任何操作,而不是主线程,可能会发生坏事(像这样)

3)复制你的项目,这样你就可以自由地弄乱它,然后尝试一堆东西:

  • 而不是多个图像,总是加载相同的图像,但保持代码的其他部分不变 - 事情会改变吗?

  • 在您创建的将保存/保留图像的任何子类中,在 dealloc 中放置一条日志消息,以查看这些对象是否实际上正在被释放。

  • 子类 UIImageView,将其用于图像,并记录 dealloc

  • 子类 UIImage,将其用于这些图像,记录 dealloc

4)我很难相信 imageio 有一个缺陷可以做到这一点,但你可以做的是切换到使用 imageWithData,并自己加载数据。当您实际读取数据时使用 F_NOCACHE 标志 - SO上有其他代码说明如何执行此操作,您可以搜索它(我回答了一个问题)。

如果您可以创建一个带有此缺陷的演示项目,那么调试它会比仅仅猜测要做什么要容易得多。记录得到 dealloc'd 的类有很长的路要走,因为您会立即看到没有释放的内容,然后更好地关注问题。

于 2013-05-07T12:16:13.390 回答
2

除了 David H 的回答之外,我还建议遇到此问题的任何人也检查是否在不需要时调用UIDocument了您的视图控制器、模型、 (如果您使用它)的反初始化程序。

如果您没有正确释放这些类并且它们包含 UIKit 引用的图像/VDO/内容数据,那么这可能会导致您看到VM: ImageIO内存使用量一直在增加,但在使用时却没有看到内存泄漏Instruments,因为这些内容现在由 UIKit 在内部保留。

我也遇到过这个问题,两次,在我的情况下,由于不相关的问题,我的模型的反初始化器从未被调用过。通过修复那些不相关的问题并确保我的模型被释放,这些VM: ImageIO持续增长就消失了。

在此处输入图像描述

于 2018-01-14T10:19:17.467 回答