我经常在代码中使用DateFormatter,没有发现任何问题,但后来我决定对一个类进行大量的迭代测试--我注意到了一个巨大的内存泄漏。
泄漏的原因是DateFormatter。
简单代码:
var dateFormatter:DateFormatter
dateFormatter = DateFormatter()
let date : Date = Date()
for _ in 1...100000000 {
_ = dateFormatter.string(from: date)
}没有泄漏。每个进程的5.9MB全部运行时。
但是当我使用dateFormat时
var dateFormatter:DateFormatter
dateFormatter = DateFormatter()
let date : Date = Date()
dateFormatter!.dateFormat = "yyyyMMddHHmmssSSS"
for _ in 1...100000000 {
_ = dateFormatter.string(from: date)
}在运行时结束时使用4 GB内存。
如果我用:
dateFormatter.dateFormat = "yyyyMMdd"没有泄漏。
如果我用:
dateFormatter.dateFormat = "yyyyMMddHH"漏水。
发布于 2019-07-27 02:40:37
在第一个例子中,您正在创建零长度字符串。修改您的代码以打印出来;您在日志中看不到任何内容。尝试将日期格式化程序的输出分配给一个变量,并通过在循环中放置一个断点来检查它的值;该值总是一个空字符串。这将解释为什么内存使用率仍然像它一样低。
在第二个示例中,您将根据日期格式创建字符串。如前所述,检查日期格式化程序中的值,您将看到。这就解释了为什么你在快速耗尽你的物理内存:你在那个循环中创建了1亿个非空字符串。
即使在第一个例子中,这也不是最佳实践。很有可能,如果您真的需要1亿个字符串,您可以对它们执行一些操作,比如将它们放在其他地方实例化的数组中,或者诸如此类。你不想让他们在那个巨大的回路里积累。
下面是您的代码的修改版本:
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMddHHmmssSSS"
for _ in 1...100000000 {
autoreleasepool(invoking: { () -> () in
let string = dateFormatter.string(from: date)
print("\(string)")
})
}注意,我使用的是循环中的一个自动释放池闭包。这确保了我在循环的每一次传递中创建的字符串在下一次迭代之前被取消分配。在这个闭包中,你可以用这个字符串做你想做的任何事情。您可以在其中创建任意数量的值,并且它们都将在循环的下一次迭代之前被释放。在我的机器上,每一件事都会以16.2 MB的内存消耗。你的里程可能会不同。
在你的努力中向你致以最良好的祝愿。
https://stackoverflow.com/questions/57226816
复制相似问题