如何在UIImage上绘图时修复此内存泄漏?

时间:2015-06-28 23:20:41

标签: ios memory-leaks uiimage

以下问题的附录。

我们已经将已分配内存的增长跟踪到指向UIImages列表的NSMutableArray。 NSMutable数组在一个方法中。它没有指向它的外部指针,强或弱。因为NSMutableArray在一个方法中 - 不应该 - 并且它指向的所有对象在方法返回后的某个时刻被自动解除分配?

我们如何确保这种情况发生?

=================

(1)首先,调用此代码会导致内存泄漏还是我们应该在其他地方寻找?

(在我们看来,这个代码确实泄漏了,因为当我们查看Apple的Instruments时,运行此代码似乎从CVPixelBuffer创建了一个1.19MB mallocs的字符串 - 并且跳过代码避免了这一点。另外,malloc分配大小不断在整个执行周期中爬行,似乎永远不会回收。添加@autorelease池减少了峰值内存使用并帮助延长应用程序崩溃 - 但基线内存使用量稳步增加,最大的罪魁祸首是这些1.19MB mallocs。) image2是现有的UIImage。

image2 = [self imageByDrawingCircleOnImage:image2 withX:newX withY:newY withColor:color];

- (UIImage *)imageByDrawingCircleOnImage:(UIImage *)image withX:(int)x withY:(int)y withColor:(UIColor *)color
{
    UIGraphicsBeginImageContext(image.size);
    [image drawAtPoint:CGPointZero];
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [color setStroke];
    CGRect shape = CGRectMake(x-10, y-10, 20, 20);
    shape = CGRectInset(shape, 0, 0);
    CGContextStrokeEllipseInRect(ctx, shape);
    UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return retImage;
}

(2)其次,如果此代码确实泄漏,那么我们如何防止泄漏,更重要的是,当我们快速连续多次调用此方法时,防止内存不足导致崩溃?我们注意到内存使用量激增,因为我们多次调用此方法会导致崩溃。问题是我们如何确保快速释放丢弃的UIImages,以便在多次调用此方法时应用程序不会因内存不足而崩溃。

2 个答案:

答案 0 :(得分:2)

  

运行此代码似乎是从CVPixelBuffer

创建一个1.19MB mallocs的字符串

但是不要错误地调用内存使用内存泄漏。只有在永远无法回收使用过的内存时,它才会泄漏。你还没有证明这一点。

许多操作使用内存 - 但是如果操作执行一次并不重要,因为那时代码结束并且内存被回收。

只有当你的代码继续运行时才会出现问题,可能会循环,以便回收内存永远不会有机会;在这种情况下,您可以通过将循环的每次迭代包装在@autoreleasepool块中来提供这样的机会。

答案 1 :(得分:1)

我们在其他地方发现了泄漏。我们需要发布一个pixelBuffer。我们从CGI图像中获取了一个pixelBuffer,并将缓冲区添加到AVAssetWriterInputPixelBufferAdaptor中 - 但它从未发布过。

在创建缓冲区的代码之后:

    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, 480,
                    640, kCVPixelFormatType_32ARGB, 
                    (__bridge CFDictionaryRef) options, 
                    &pxbuffer);

...以及将其附加到AVAssetWriter的代码:

     [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

...我们需要按此SO answer添加此版本代码:

     CVPixelBufferRelease(buffer);

添加该代码后,应用程序的内存占用量保持不变。

此外,我们将@autoreleasepool {}命令添加到视频编写代码中的几个点,并且内存使用率峰值变平,这也稳定了应用程序。

我们的简单结论是,SO应该获得诺贝尔奖。