CoreImage Memory Termination Issue

Hello, this is the code I'm using to save a screenshot of the current metal view.
After saving 180 images, the app crashes with a memory issue.
Code Block swift
autoreleasepool{
                    let   fileName = captureFileName + String(currentIdx) + ".png"
                    if let imageRef = view.currentDrawable!.texture.toImage() {
                        let uiImage:UIImage = UIImage.init(cgImage: imageRef)
                        if let data = uiImage.jpegData(compressionQuality: 1.0) {
                            let filename = getDocumentsDirectory().appendingPathComponent(fileName)
                            try? data.write(to: filename)
                        }
                    }
}


Code Block swift
extension MTLTexture {
    func bytes() -> UnsafeMutableRawPointer {
        let width = self.width
        let height   = self.height
        let rowBytes = self.width * 4
        let p = malloc(width * height * 4)
        self.getBytes(p!, bytesPerRow: rowBytes, from: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0)
        return p!
    }
    func toImage() -> CGImage? {
        
        let p = bytes()
        let pColorSpace = CGColorSpaceCreateDeviceRGB()
        let rawBitmapInfo = CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
        let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo)
        let selftureSize = self.width * self.height * 4
        let rowBytes = self.width * 4
        let releaseMaskImagePixelData: CGDataProviderReleaseDataCallback = { (info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size: Int) -> () in
            
            return
        }
        let provider = CGDataProvider(dataInfo: nil, data: p, size: selftureSize, releaseData: releaseMaskImagePixelData)
        let cgImageRef = CGImage(width: self.width, height: self.height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: rowBytes, space: pColorSpace, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
        
        
        return cgImageRef
    }
}



I figured out that the malloced p in the extension function causes the memory issue but how do I free this after using the pointed data inside autoreleasepool?

Thanks!



Replies

It appears that you'll need to restructure your code in such a way that you maintain a reference to the malloc'd memory backing the CGImage until you create the UIImage, and then you would free that memory immediately afterwards.
It looks like you are using p as the backing data for your data provider, so you should also tie its lifetime to the provider’s. Since CGDataProvider expects you to release your provider data as part of its release callback, you should free your pointer inside the callback you’ve provided, i.e. releaseMaskImagePixelData. The release callback will receive p as the data argument, so you don’t need to provide p yourself.