如何找出哪个课程占用的内存最多?

时间:2017-12-26 06:39:08

标签: ios swift memory-leaks instruments

我对我的iOS应用程序做了一个看似无害的变化,应用程序崩溃了,因为随着应用程序的运行,内存消耗不断增加,直到崩溃。这可能是内存消耗增加了10倍。

如何找出哪个类或结构对此负责?我正在寻找类似的东西:

CVPixelBuffer:800MB CMSampleBuffer:100MB CIImage:50MB

我查看了Xcode的内存调试器和Instruments,但没有找到任何内容。

1 个答案:

答案 0 :(得分:0)

这是CIFilter initialiser中的内存泄漏。以下是重现的步骤:

  1. 使用AVFoundation捕获原始样本缓冲区。
  2. 调用CMSampleBufferGetImageBuffer()获取CVPixelBuffer:
  3. 创建一个CIFilter:
  4. 请注意,CIFilter会被丢弃。
  5. 完成上述所有步骤后,请返回步骤1,重复100次。
  6. 以下是代码:

    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
    let metadata = CMCopyDictionaryOfAttachments(nil, sampleBuffer, kCMAttachmentMode_ShouldPropagate)!
    _ = CIFilter(cvPixelBuffer: pixelBuffer, properties: metadata)
    

    预期结果:

    创建Swift对象并将其丢弃不会泄漏内存。

    实际结果:

    • 在iOS杀死应用程序之前,内存使用量以无限制的方式增长到超过1 GB。
    • 注释掉创建CIFilter的行消除了这个问题。
    • 使用dngPhotoDataRepresentation()将RAW示例缓冲区转换为NSData并将其传递给CIFilter初始化程序可以消除此问题,但似乎更慢。
    • CVPixelBuffer似乎没有发布,因为CIFilter(或iOS内部的一些其他代码正在泄漏)。我通过创建一个对CVPixelBuffer的弱引用来验证。如果缓冲区被释放,弱引用应该变为nil,但它不会。
    • 捕获BGRA(而不是RAW)样本缓冲区并将其转换为CIImage不会泄漏内存:

      _ = CIImage(cvImageBuffer:pixelBuffer,options:[kCIImageProperties:metadata])

    这是在iPhone 7 Plus和iPhone X上的iOS 11上。