Swift 怎么手动释放内存?

2017-08-10 18:02:44 +08:00
 DingSoung

Swift 不支持 MRC 我的情况

for  0..<1000 {
     creat image context
      get image
      end image context
}

在住线程上执行,context 要在循环执行完后在 runloop 上回收,这样 context 越来越多,内存会爆掉

已经试过的办法

for  0..<100 {
   autoreleasepool {
         creat image context
          get image
          end image context
    }
}

```Swift
for  0..<100 {
        creat image context
        get image
        end image context
       dispatch_async {
          context = nil
      }
}

我现在的做法是

creat big image context
for 0...100 {
   creat image 
   adjust context
}
end image context

但是这样也是很有限的,image context 非常占内存 图片 4000 * 12000 的时候占到 200 多 MB

所以不知道 iOS 有没有其他的 API, 可以生成超大的图(4000 * 100000) 但是可以一点一点的生成并写到文件,同时可以不断的手动创建对象和释放内存

5944 次点击
所在节点    iDev
9 条回复
ma125125t
2017-08-10 18:11:57 +08:00
你这是要做 ML 吗?
gggxxxx
2017-08-10 18:42:42 +08:00
swift 是 arc,arc 是 mrc 的傻瓜版,就是负值成 nil 就行了。
obj = nil
DingSoung
2017-08-10 19:02:47 +08:00
@ma125125t 导出一个 table
@gggxxxx 设置 nil 也不是立即释放的
congeec
2017-08-10 21:56:27 +08:00
我不用 swift,不过有点不明白。难道 context 出作用域,其引用计数不会-1 么?
nicevar
2017-08-11 10:43:06 +08:00
gc 正常情况赋值空只是标记一下,本来就是不会立即释放的,系统会决定什么时候释放,所以就会有系统还没来得及释放回收的时候突然分配一块大的内存导致 crash 的情况
lingoerer
2017-08-11 13:29:40 +08:00
楼主给的信息实在是有限,没法确定楼主的问题出在哪里
以下内容基于这么一个推测:即楼主要做的事情是通过大量计算自动地批量生成图片,图片的量大,且每张图片的尺寸也都非常大,而楼主使用的是 UIKit 中提供的类似 UIGraphicsBeginImageContext 和 UIGraphicsEndImageContext 之类的简单接口。
一句话,这个问题没有简单无脑的解决方案,但稍微深入一下,办法却还是很多。
1. UIKit/Foundation 中提供的接口并不适合做这件事情,这与语言无关,即使用 objc 通过 mrc 绕开 arc 的坑也是一样。性能非常堪忧。
对于图片的绘制,楼主应该考虑使用 Metal 提供的 Compute Shader,将图片分阶段绘制到 MTLTexture 中。
使用 Metal 确实存在一些门槛,如果不会的话,试试查阅一些第三方库,比如 https://github.com/BradLarson/GPUImage 说不定有提供对于你的需求现成的方法。
2. 注意 Swift 中并不是不支持内存管理,Swift 其实提供有一系列类似 UnsafeBufferPointer 的工具来管理内存,楼主可以仔细读一下官方的文档:
https://developer.apple.com/documentation/swift/manual_memory_management
这一系列方法应该就是对楼主问题最直接的答案。
3. 最后,出乎意料地,很多人并不知道许多 Unix C Level 的函数在 Swift 中是可以直接调用的(并不是私有 API ),比如 mmap ……
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/mmap.2.html
具体例子我记得苹果去年的 ImageRecognition Demo 中有,使用 mmap 将神经网络的参数文件直接映射进内存空间,以节省内存使用,楼主这里可以反过来使用它来写文件(需要 Import Darwin )。
DingSoung
2017-08-11 14:21:46 +08:00
@lingoerer 确实,image context 基本用到极限了。得从图片编码得角度去分块处理。
DingSoung
2017-08-11 14:23:35 +08:00
@lingoerer 谢谢提供方向
jessehao7
2017-08-13 10:38:27 +08:00
1. 如果 swift 的 arc 和 obj-c 的 arc 一样的话,设 nil (=release,但!=dealloc )且引用计数减到 0 就确实是立即释放内存的,被标记的空间可以被复用。
2. 不行的话就搞成 struct。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/381998

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX