UIGraphicsGetImageFromCurrentImageContext memory leak with previews

佐手、 提交于 2019-11-26 20:43:51

The problem is this:

UIGraphicsGetImageFromCurrentImageContext()

returns an autoreleased UIImage. The autorelease pool holds on to this image until your code returns control to the runloop, which you do not do for a long time. To solve this problem, you would have to create and drain a fresh autorelease pool on every iteration (or every few iterations) of your while loop.

I know it's an old question, but I've just been banging my head against the wall on this for a few hours. In my app repeatedly calling

UIImage *image = UIGraphicsGetImageFromCurrentImageContext()

in a loop does hold on to the memory despite me calling image = nil; Not sure how long the app would keep hold of the memory before freeing, but it's certainly long enough for my app to get a memory warning then crash.

I managed to solve it finally by wrapping the code that calls / uses the image from UIGraphicsGetImageFromCurrentImageContext() in @autoreleasepool. So I have:

@autoreleasepool {
    UIImage *image = [self imageWithView:_outputImageView]; //create the image
    [movie addImage:image frameNum:i fps:kFramesPerSec];    //use the image as a frame in movie
    image = nil;
}

Hope that might help someone.

MMV

For future reference here's what I did to solve this (tested in Swift 4).

I was calling the function below for every new image downloaded from the internet (on a utility queue). Before implementing the autorelease pool it would crash after processing about 100.

For simplicity, in the resizeImage function I've removed needed code except for the autoreleasepool and the part that was leaking.

private func resizeImage(image: UIImage, toHeight: CGFloat) -> UIImage {
    return autoreleasepool { () -> UIImage in
        [...]

        let newImage = UIGraphicsGetImageFromCurrentImageContext() //Leaked
        UIGraphicsEndImageContext()

        return newImage!
    }

}

I hope this helps!

Ricardo de Cillo

Is this code running on the main thread? The documentation of the UIGraphicsGetImageFromCurrentImageContext (link) says it must run that way.

I've had the same problem working with big images. Adding a padding to an image or applying a filter resulted with 200MB of memory allocation without releasing it while the image was on the screen.

Found a working way to fix this problem:

extension UIImage {
  func release() -> UIImage? {
    guard let data = UIImageJPEGRepresentation(self, 1.0) else { return nil }
    return UIImage(data: data)
  }
}

Also tried it with UIImagePNGRepresentation but it seems to not release the allocation neither.

your line of crash you can update it like following

get one UIimage out of loop

rendered_image = UIGraphicsGetImageFromCurrentImageContext();

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!