DHSmartScreenshot
DHSmartScreenshot copied to clipboard
use up memory
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
背景
我今天写了一个Swift版本的,然后我发现内存开销非常大,主要在 UIGraphicsBeginImageContextWithOptions
和 UIGraphicsGetImageFromCurrentImageContext
这两个地方
寻找解决办法
我尝试过 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;
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)