DHSmartScreenshot icon indicating copy to clipboard operation
DHSmartScreenshot copied to clipboard

use up memory

Open DingSoung opened this issue 7 years ago • 2 comments

when number of row > 1000, memory use up you may consider generate middle image and release image of rows, in case of add to much image to array

DingSoung avatar Aug 09 '17 10:08 DingSoung

背景

我今天写了一个Swift版本的,然后我发现内存开销非常大,主要在 UIGraphicsBeginImageContextWithOptionsUIGraphicsGetImageFromCurrentImageContext 这两个地方 2017-08-09 9 35 41

寻找解决办法

我尝试过 autoreleasepool1

autoreleasepool {
    if let image = self.imageForSection(at: section,
                                        fromRow: 0,
                                        to: self.numberOfRows(inSection: section),
                                        withHeader: true,
                                        footer: true) {
             images.append(image)
             if images.count > 5 {
                   if let image = images.verticalImage {
                        images.removeAll() //? release memory?
                            images.append(image)
                        }
                    }
            }
       }
}

还有异步线程2

var image: UIImage?
DispatchQueue.global().async {
      UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, UIScreen.main.scale);
      if let contex = UIGraphicsGetCurrentContext() {
           contex.setAlpha(alpha)
           self.layer.render(in: contex)
           image = UIGraphicsGetImageFromCurrentImageContext()
       }
       UIGraphicsEndImageContext();
}
return image;

还有这里参考3

var temp = self.image(alpha:1)
let image = temp
temp = nil
DispatchQueue.global().async {
  _ = temp
}
return image;

思考

后来我思考了一下我们的结构

main thread runloop -> action -> some function -> for loop -> CoreGraph Image context

而ARC情况下的内存释放

main thread runloop -> recycle memory

事件还没有完,main thread runloop永远无法走到下一个内存释放的时机,而我们在这个事件中创造了很多个context

并且由于Swift不支持MRC手动释放context,所以过多创建context而不返回runloop是不可行的

至于方法2可行,是因为context在其他线程上释放了

解决办法

只创建一个context,所有的操作都在这里面完成,伪代码如下

begin context;
for ... {
  creat image from current context
}
end context;

DingSoung avatar Aug 09 '17 13:08 DingSoung

I have do some improve and get a result below(iOS 10.3, iPhone 6 Plus, use over 500MB memory) almost reach limit (iOS will terminate app witch use half of total memory)

img_0434

DingSoung avatar Aug 10 '17 08:08 DingSoung