Running out of memory analyzing images with ImageRequestHandler

Hi,

I'm trying to analyze images in my Photos library with the following code:

func analyzeImages(_ inputIDs: [String])
    {
        let manager = PHImageManager.default()
        let option = PHImageRequestOptions()
        option.isSynchronous = true
        option.isNetworkAccessAllowed = true
        option.resizeMode = .none
        option.deliveryMode = .highQualityFormat
        let concurrentTasks=1
        let clock = ContinuousClock()

        let duration = clock.measure {
            
            let group = DispatchGroup()
            let sema = DispatchSemaphore(value: concurrentTasks)
            for entry in inputIDs {
                if let asset=PHAsset.fetchAssets(withLocalIdentifiers: [entry], options: nil).firstObject {
                    print("analyzing asset: \(entry)")
                    group.enter()
                    sema.wait()
                    manager.requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: option) { (result, info) in
                        if let result = result {
                            Task {
                                print("retrieved asset: \(entry)")
                                let aestheticsRequest = CalculateImageAestheticsScoresRequest()
                                let fingerprintRequest = GenerateImageFeaturePrintRequest()
                                let inputImage = result.cgImage!
                                let handler = ImageRequestHandler(inputImage)
                                let (aesthetics,fingerprint) = try await handler.perform(aestheticsRequest, fingerprintRequest)
//                                save Results
                                print("finished asset: \(entry)")
                                sema.signal()
                                group.leave()
                            }
                        }
                        else {
                            group.leave()
                        }
                        
                    }
                }
            }
            group.wait()
        }
        print("analyzeImages: Duration \(duration)")
    }

When running this code, only two requests are being processed simultaneously (due to to the semaphore)... However, if I call the function with a large list of images (>100), memory usage balloons over 1.6GB and the app crashes. If I call with a smaller number of images, the loop completes and the memory is freed.

When I use instruments to look for memory leaks, it indicates no memory leaks are found, but there are 150+ VM:IOSurfaces allocated by CMPhoto, CoreVideo and CoreGraphics @ 35MB each. Shouldn't each surface be released when the task is complete?

Answered by DTS Engineer in 816314022

Hello @rrrpdx,

Can you try putting an autoreleasepool inside of your for-in loop?

Best regards,

Greg

Could this be a problem with the ARC memory management of Swift? Most probable you have to use a @autoreleasepool at the right level to get rid of of autoreleased objects during your loop.

Accepted Answer

Hello @rrrpdx,

Can you try putting an autoreleasepool inside of your for-in loop?

Best regards,

Greg

Running out of memory analyzing images with ImageRequestHandler
 
 
Q