- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我只在 iOS 9 上观察到这种行为; iOS 8 正常运行。
我怀疑这可能是 SDK 上的一个错误,我已经向 Apple (22644754) 打开了一个雷达,但我发现它很奇怪,我觉得我可能错过了一个电话或一个步骤来避免泄漏。
我观察到每次调用 CIContext.createCGImage 时,内存使用量都会增加。棘手的部分是内存增加发生在应用程序之外。
如果您查看 Xcode 的“内存报告”,内存增加会显示在“其他进程”部分。
基本上,导致问题的原因如下(我已将代码严格简化为重现泄漏所必需的部分):
首先,我创建一个由 EAGLContext 支持的 CIContext:
let glContext = EAGLContext(API: .OpenGLES2)!
let ciContext = CIContext(EAGLContext: glContext, options: [kCIContextOutputColorSpace : NSNull()])
然后,我使用以下方法渲染图像:
let input = CIImage(image: UIImage(named: "DummyImage")!)!
ciContext.createCGImage(input, fromRect: input.extent)
DummyImage 只是一个示例图像文件。泄漏与此图像的大小直接相关,因此最好使用大的图像以使问题更加明显。
如您所见,我没有使用任何 CIFilter(使用它们会导致相同的结果),并且我没有捕获生成的图像(即使我捕获了它,我也无法使用 CGImageRelease,因为对象是自动管理)。
如果渲染代码执行的次数足够多,内存会增长太多,以至于正在运行的应用程序会被杀死。
一个有趣的观察是,销毁 CIContext 并没有什么不同,但销毁 EAGLContext 确实会返回占用的内存。这让我认为泄漏发生在 OpenGL 端。
我的代码中是否遗漏了任何可能导致泄漏的内容?我可以打电话释放 EAGLContext 占用的内存吗? (一直重新创建它不是一种选择,因为它是一项代价高昂的操作)。
我创建了一个简单的项目来重现该问题。您可以在以下位置找到它:
https://www.dropbox.com/s/zm19u8rmujv6jet/EAGLContextLeakDemo.zip?dl=0
重现的步骤是:
最佳答案
我解决它的方法是将上下文呈现到缓冲区中,然后将其以 JPG 格式写入文件。我将不得不进一步了解如何在旧版 iOS 设备上优化此流程,但与 createCGImage 相比,它似乎运行良好。此代码对于将 CIImage 转换为 JPEG 或位图 NSData 也很有用。完整的示例代码可以在这里看到:
https://github.com/mmackh/IPDFCameraViewController
static CIContext *ctx = nil;
if (!ctx)
{
ctx = [CIContext contextWithOptions:@{kCIContextWorkingColorSpace:[NSNull null]}];
}
CGSize bounds = enhancedImage.extent.size;
int bytesPerPixel = 8;
uint rowBytes = bytesPerPixel * bounds.width;
uint totalBytes = rowBytes * bounds.height;
uint8_t *byteBuffer = malloc(totalBytes);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
[ctx render:enhancedImage toBitmap:byteBuffer rowBytes:rowBytes bounds:enhancedImage.extent format:kCIFormatRGBA8 colorSpace:colorSpace];
CGContextRef bitmapContext = CGBitmapContextCreate(byteBuffer,bounds.width,bounds.height,bytesPerPixel,rowBytes,colorSpace,kCGImageAlphaNoneSkipLast);
CGImageRef imgRef = CGBitmapContextCreateImage(bitmapContext);
CGColorSpaceRelease(colorSpace);
CGContextRelease(bitmapContext);
free(byteBuffer);
if (imgRef == NULL) { goto release; }
CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:filePath];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImage(destination, imgRef, nil);
CGImageDestinationFinalize(destination);
CFRelease(destination);
success = YES;
goto release;
release :
{
CFRelease(imgRef);
if (success)
{
//completionHandler(filePath);
}
dispatch_resume(_captureQueue);
}
关于ios - 为什么 CIContext.createCGImage 会导致内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32520082/
我在做什么: 我正在从 AVFoundation 中的 didOutputSampleBuffer 获取 CMSampleBuffer 并运行一些过滤器并将它们输出到 UIImage> 每次代表吐出一
我只在 iOS 9 上观察到这种行为; iOS 8 正常运行。 我怀疑这可能是 SDK 上的一个错误,我已经向 Apple (22644754) 打开了一个雷达,但我发现它很奇怪,我觉得我可能错过了一
代码: enum GradientDirection { case up case left case upLeft case upRight } extension
我正在尝试模糊图像的一部分: extension UIImage { func blur(rect: CGRect, radius: CGFloat) -> UIImage? {
我正在对图像应用多个 CIFilter,但是当我应用第二个过滤器时,我一直得到 nil 结果。我创建了裁剪和旋转功能,如下所示: func crop(_ image: CIImage) -> CIIm
我是一名优秀的程序员,十分优秀!