内存泄漏:通过简单的设备运动日志记录内存使用量稳步增加

Memory leak: steady increase in memory usage with simple device motion logging

考虑这个简单的 Swift 代码,它将设备运动数据记录到磁盘上的 CSV 文件中。

let motionManager = CMMotionManager() 
var handle: NSFileHandle? = nil

override func viewDidLoad() {
    super.viewDidLoad()

    let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let file = documents.stringByAppendingPathComponent("/data.csv")

    NSFileManager.defaultManager().createFileAtPath(file, contents: nil, attributes: nil)
    handle = NSFileHandle(forUpdatingAtPath: file)

    motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {(data, error) in
        let data_points = [data.timestamp, data.attitude.roll, data.attitude.pitch, data.attitude.yaw, data.userAcceleration.x,
            data.userAcceleration.y, data.userAcceleration.z, data.rotationRate.x, data.rotationRate.y, data.rotationRate.z]

        let line = ",".join(data_points.map { [=10=].description }) + "\n"
        let encoded = line.dataUsingEncoding(NSUTF8StringEncoding)!

        self.handle!.writeData(encoded)
    })
}

我已经坚持了好几天了。似乎有内存泄漏,因为内存 消耗量稳步增加,直到 OS 因超出资源而暂停应用程序。

此应用能够 运行 长时间不间断运行至关重要。一些注意事项:

有什么指点吗?我尝试过使用 Instruments,但我不具备有效使用它的技能。看来内存使用量的爆炸式增长是由 __NSOperationInternal 引起的。这是一个示例 Instruments trace.

谢谢。

先看我的这个回答:

您不应该在调试器中查看内存图;只相信 Instruments 告诉你的。在 Swift.

中,调试构建和发布构建的内存管理方式非常不同

其次,如果仍有问题,请尝试将处理程序的内部包裹在 autoreleasepool 闭包中。但是,我不认为这会有所作为(因为这不是循环),而且我不认为这是必要的,因为我怀疑使用 Instruments 会揭示一开始就没有任何问题.但是,autoreleasepool 调用将确保自动释放的对象没有机会累积。