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

时间:2015-02-16 15:43:01

标签: ios objective-c swift memory-management memory-leaks

考虑这个简单的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 { $0.description }) + "\n"
        let encoded = line.dataUsingEncoding(NSUTF8StringEncoding)!

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

我已经被困在这几天了。似乎存在内存泄漏,如内存 消费稳步增长,直到操作系统暂停应用程序超出资源。

Memory usage

这个应用程序能够长时间不间断地运行至关重要。一些说明:

  • 我尝试过使用NSOutputStream和CSV编写库(CHCSVParser),但问题仍然存在
  • 异步执行日志记录代码(在startDeviceMotionUpdatesToQueue中包装dispatch_async)不会消除此问题
  • 在后台NSOperationQueue 执行传感器数据处理可以解决问题(仅当maxConcurrentOperationCount> = 2时)。但是,这会导致文件写入时出现并发问题:输出文件在相互交织的行之间出现乱码。
  • 仅在记录加速计数据时似乎没有出现此问题,但在记录多个传感器(例如加速度计+陀螺仪)时似乎确实出现了问题。或许存在触发此问题的文件写入吞吐量阈值?
  • 内存峰值似乎以大约10秒的间隔隔开(上图中的步骤)。也许这表明了什么? (可能是内存检测基础结构的工件,或者可能是它的垃圾收集)

任何指针?我曾尝试过使用乐器,但我不具备有效使用乐器的技能。爆炸式内存使用似乎是由__NSOperationInternal引起的。这是一个示例Instruments trace

谢谢。

1 个答案:

答案 0 :(得分:2)

首先,看看我的这个答案:

https://stackoverflow.com/a/28566113/341994

您不应该在调试器中查看内存图;只相信乐器告诉你的东西。在Swift中,调试版本和发布版本的内存管理方式截然不同。

其次,如果仍有问题,请尝试将处理程序的内部包装在autoreleasepool闭包中。我不认为这会产生影响,但是(因为这不是一个循环),我不认为它是必要的,因为我怀疑使用仪器将揭示首先从来没有任何问题。但是,autoreleasepool调用将确保自动释放的对象没有机会累积。