以下问题的附录。
我们已经将已分配内存的增长跟踪到指向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,以便在多次调用此方法时应用程序不会因内存不足而崩溃。
答案 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应该获得诺贝尔奖。