在 iOS 15.6 上使用视觉文本识别 (Swift),每次识别内存会增加约 25MB。无论如何要释放内存吗?

问题描述 投票:0回答:1

我需要一次对数百张图像进行文本识别,但每次,内存都会增加约 25mb+。 我已经在互联网上搜索过,但找不到导致记忆保留的原因或如何释放它。 通过插入中断,我可以看到每次调用 imageRequestHandler.perform() 时都会发生大小跳跃。 下面是相关代码。 有什么建议吗?

    func textRecognition(image:CGImage) {
                
        let textRecognitionRequest = VNRecognizeTextRequest(
            completionHandler: self.handleDetectedText)
        textRecognitionRequest.recognitionLevel = .accurate
        textRecognitionRequest.recognitionLanguages = ["en_US"]
        textRecognitionRequest.usesLanguageCorrection = false
        
        // request handler
        let textRequest = [textRecognitionRequest]
        let imageRequestHandler = VNImageRequestHandler(cgImage: image, orientation: .up, options: [:])
        DispatchQueue.global(qos: .userInitiated).async {
            do {
                // perform request
                try imageRequestHandler.perform(textRequest)
            } catch let error {
                print("Error \(error)")
            }
        }
    }
    
    func handleDetectedText(request: VNRequest?, error:Error?){
        if let error = error {  print("ERROR: \(error)"); return  }
        guard let results = request?.results, results.count > 0 else {
            DispatchQueue.main.async {
                self.result_field.isEnabled=false
                self.result_field.text = "Scan failed - Retry"
                let desc = NSMutableAttributedString(string: "Retake Photo", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22, weight: .regular)])
                self.take_button.setAttributedTitle(desc, for: UIControl.State.normal)
                self.take_button.isHidden = false
                self.take_button.isEnabled = true
            }
            return // code to process the text replaced by the 'return' statement
        }}}
ios swift memory-leaks text-recognition apple-vision
1个回答
1
投票

我建议进行分析,看看是什么占用了内存。但总的来说,我认为有两个领域可以探索潜在的改进:

  1. 图像可能会导致更高的内存使用量。我们(开发人员)的倾向是捕捉“最佳”形象。然而,文本识别可能不需要巨大的高质量图像(并且对于较小的图像给出相同的结果)。因此,请尝试在捕获和/或处理时缩小图像:

    • AVCapturePhotoSettings
      进行实验,即
      photoQualityPrioritization
      和照片
      format
    • 尝试减小
      CGImage
      尺寸/也许将其设为黑白。但这些操作也并非没有成本。或者尝试将
      CVPixelBuffer
      直接传递到
      VNImageRequestHandler
      (不转换为 CGImage - 如果您从相机拍摄图像)
  2. 看看

    autoreleasepool
    是否有利于您的内存使用。最明显的位置是
    imageRequestHandler.perform
    :尝试在专用队列上执行它,并为该队列设置
    autoreleaseFrequency: .workItem

private static let performQueue = DispatchQueue(
        label: "your label",
        qos: .userInitiated,
        autoreleaseFrequency: .workItem, // <-- switching from default .never
        target: .global(qos: .userInitiated) <-- same priority as the one you have
    )

// ...

Self.performQueue.async {
    try imageRequestHandler.perform(textRequest)
}

它有什么作用:

队列在块执行之前配置一个自动释放池,并在块执行完成后释放该池中的对象。

由于识别请求可能有很多临时对象,您可能会从此设置中受益,因为这些对象将在请求完成后立即释放(而不是“最终”)。不能保证它会有所帮助,但值得一试。

再次强调,这些只是建议,但如果减少内存对您来说如此重要,那么确实需要“性能评估”。虽然说实话我觉得25MB还是蛮合理的。

© www.soinside.com 2019 - 2024. All rights reserved.