有人可以澄清关于Swift内存管理的一件事吗?
我有以下app delegate:
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
private let _queue = NSOperationQueue()
func applicationDidFinishLaunching(aNotification: NSNotification) {
_queue.maxConcurrentOperationCount = 1
_queue.addOperation(Operation())
_queue.addOperation(Operation())
_queue.addOperation(Operation())
}
}
private class Operation: NSOperation {
override func main() {
autoreleasepool {
var d = [String: AnyObject]()
for i in 1...1000 {
d[i.description] = Repeat(count: 10000, repeatedValue: "ABCDEF").joinWithSeparator("") // tested with repeat or just large string
}
d.removeAll()
}
}
}
应用程序启动后,我将三个同步操作排入队列。每个操作只创建非常大的字典(struct),包含非常大的字符串(也是结构)。
由于所有创建的数据都是值类型而且没有捕获任何内容,因此我认为当main函数结束时内存应该被释放。事实上,为了确保释放内存,我添加了d.RemoveAll()
。
完成所有操作后,Activity Monitor会显示以下信息:
我的应用程序仍然占用 26.7mb ,但如果我删除所有_queue.addOperation(Operation())
,那么它将是 7mb 。为什么在所有操作完成后还没有释放额外的19mb内存?
@Lou Franco 我将app delegate更改为
func applicationDidFinishLaunching(aNotification: NSNotification) {
for _ in 1...100 {
_queue.addOperation(Operation())
}
}
现在8个操作同时运行。完成所有操作后约40mb左右无人回收。我试图排队 100000次操作。应用程序崩溃40分钟。它的内存使用量是 600 ... 1000mb ,但是我无法等到所有操作完成。
答案 0 :(得分:0)
你没有泄漏。该过程不会立即将所有内存返回给操作系统 - 这将非常浪费且昂贵。内存返回import -window root imagefile.png
空闲内存列表。
运行测试代码我实际上看到内存爬升然后在每次操作完成后丢弃。
我还怀疑,在碎片化的情况下,内存不会返回给操作系统(某些对象在大量空闲字节之间仍然存在)。您的示例的这个变体达到几百MB的高水位标记,然后在操作完成时回落到13.8。通过分配连续的缓冲区,我们知道有很多大块可以返回给操作系统。
malloc