Swift中的内存管理:在NSOperation结束后,内存不会被释放

时间:2016-04-12 13:27:26

标签: ios swift multithreading macos cocoa

有人可以澄清关于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会显示以下信息: enter image description here

我的应用程序仍然占用 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 ,但是我无法等到所有操作完成。

1 个答案:

答案 0 :(得分:0)

你没有泄漏。该过程不会立即将所有内存返回给操作系统 - 这将非常浪费且昂贵。内存返回import -window root imagefile.png 空闲内存列表。

运行测试代码我实际上看到内存爬升然后在每次操作完成后丢弃。

我还怀疑,在碎片化的情况下,内存不会返回给操作系统(某些对象在大量空闲字节之间仍然存在)。您的示例的这个变体达到几百MB的高水位标记,然后在操作完成时回落到13.8。通过分配连续的缓冲区,我们知道有很多大块可以返回给操作系统。

malloc