NSJSONSerialization.JSONObjectWithData泄漏内存

时间:2015-09-11 18:33:09

标签: json swift memory memory-leaks

我有一个使用NSJSONSerialization.JSONObjectWithData的函数,但是没有释放一些内存。 因此,我追踪泄漏发生的位置并使用以下功能对其进行测试:

private func test() {
    for var i = 0; i < 100000; i++ {
        let toParse = NSString(string: "{ \"Test\" : [ \"Super mega long JSON-string which is super long because it should be super long because it is easier to see the differences in memory usage with a super long JSON-string than with a short one.\" ] }").dataUsingEncoding(NSUTF8StringEncoding)!  
        let json = try! NSJSONSerialization.JSONObjectWithData(toParse, options: NSJSONReadingOptions(rawValue: 0))
    }
}   

在我调用test()之前我的应用程序的内存使用量为11 MB,之后的内存使用量为74.4 MB(即使我在我的应用程序中做了一些其他事情,让系统有时间释放存储器)...

为什么json没有被释放?

Mundi向我指出autoreleasepool我还没有尝试过(在这里插入facepalm)...所以我将代码更改为:

autoreleasepool {
    self.test()
}

这没有任何区别,因为Xcode建议,我也尝试过:

autoreleasepool({ () -> () in
    self.test()
})

但这也没有用......

P.S。:也许我应该在Swift 2.0中使用Xcode 7 GM添加。

P.P.S:test() - 函数是从

中调用的
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), {
    //... my code ...
    self.test()
})

但这不应该有任何区别......

2 个答案:

答案 0 :(得分:2)

您误解了自动释放池的工作原理。在释放池之前,自动释放池会保留已分配的内存。在自动释放池中调用循环100,000次意味着池没有机会释放任何内容,因此内存会增加。最终它会消失,当代码完成运行并释放自动释放池时,但同时你的内存使用率会上升。

正确的方式:

private func test() {
    for var i = 0; i < 100000; i++ {
        autoreleasepool {
            stuff
        }
    }
}

答案 1 :(得分:1)

正如你在问题中指出的那样,应用程序会随意释放内存,因此它仍未释放这一事实并不意味着它会导致内存紧张。

您可以尝试将测试例程封装在autoreleasepool中,类似于Objective-C。

func test()  {
    autoreleasepool {
       // do the test
    }
}