【问题标题】:What can cause different ObjC/ARC memory behaviour between Release and Debug configuration?什么会导致发布和调试配置之间的不同 ObjC/ARC 内存行为?
【发布时间】:2014-06-13 15:44:50
【问题描述】:

我正在运行一个测试,以确保通过将相关代码部分包装在一个 10 秒长的 while 循环中来正确释放对象。我在 Debug 和 Release 配置中运行了测试,结果不同。

调试(在模拟器中构建并运行):

发布(在设备上构建和运行,并使用仪器配置文件):

CPU 峰值表示创建和销毁对象的位置(每次运行有 3 个)。请注意在 Debug 构建中,内存使用量如何在繁忙循环期间逐渐上升,然后在更高的基本级别稍稍稳定下来,每次循环迭代都会发生这种情况。在发布版本中,它始终保持不变。在运行 3 次后,Debug 版本的内存使用水平明显高于 Release 版本。 (CPU 峰值在时间轴上相对于彼此偏移,但这只是因为我在不同时间按下了触发循环的按钮。

有问题的内部循环代码非常简单,基本上由一堆正确配对的mallocfree 语句以及一堆retainrelease 调用组成(由ARC提供,也验证为正确配对)。

知道是什么导致了这种行为吗?

【问题讨论】:

标签: objective-c automatic-ref-counting instruments


【解决方案1】:

许多 Cocoa-Touch 类使用缓存来提高性能。用于缓存数据的内存量可能会因总内存、可用内存以及可能的其他一些因素而异。由于您比较了 Mac 和设备的结果,因此收到不同的结果并不奇怪。

一些使用缓存的类/方法示例:

+(UIImage *)imageNamed:(NSString *)name

讨论

此方法在系统缓存中查找具有指定名称和 如果存在,则返回该对象。如果匹配的图像对象不是 已经在缓存中,此方法从 指定文件,缓存它,然后返回结果对象。

NSURLCache

NSURLCache 类实现对响应的缓存 通过将 NSURLRequest 对象映射到 URL 加载请求 NSCachedURLResponse 对象。它提供了一个复合内存和 磁盘缓存

【讨论】:

    【解决方案2】:

    在发布版本中,ARC 将尽最大努力将对象排除在自动释放池之外。它使用 objc_returnsRetainAutorelease 执行此操作并在运行时检查它。

    【讨论】:

    • 这可以解释为什么在循环期间内存使用率保持不变。但这会影响执行结束时的内存使用量高一个数量级吗?我原以为运行循环已经完成,所以池会在测试代码结束时被释放(在图表上 CPU 峰值下降到 0 的点)?
    【解决方案3】:

    一方面,该版本构建优化代码并从代码中删除调试信息。因此,应用程序包明显更小,加载它所需的内存更少。

    我认为在 Debug 构建中使用的大部分内存是实际的调试信息、僵尸跟踪等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2017-05-07
      • 1970-01-01
      相关资源
      最近更新 更多