仪器(泄漏)和NSDateFormatter

4
当我使用Instruments Leaks运行我的iPhone应用程序,并使用NSDateFormatter解析一堆NSDates时,我的内存会增加约1MB并保持不变,尽管这些NSDates在解析后应该被dealloc'd(如果它们不是新的,则我只是丢弃它们)。
我认为malloc(在下面最重的堆栈跟踪中)可能会成为NSDate的一部分,但我也认为它可能是在解析的某个中间步骤中仅使用的内存。有人知道它是哪一个或如何找出吗?
此外,是否有办法在NSDate dealloc上设置断点,以查看是否真的回收了该内存?
以下是用于解析这些日期的我的日期格式化程序的外观:
df = [[NSDateFormatter alloc] init]; 
[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"];

以下是内存占用过高并停留时的最重要堆栈跟踪信息:
   0 libSystem.B.dylib  208.80 Kb     malloc
   1 libicucore.A.dylib  868.19 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   2 libicucore.A.dylib  868.66 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   3 libicucore.A.dylib  868.67 Kb     icu::ZoneMeta::getSingleCountry(icu::UnicodeString const&, icu::UnicodeString&)
   4 libicucore.A.dylib  868.67 Kb     icu::DateFormatSymbols::initZoneStringFormat()
   5 libicucore.A.dylib  868.67 Kb     icu::DateFormatSymbols::getZoneStringFormat() const
   6 libicucore.A.dylib  868.67 Kb     icu::SimpleDateFormat::subParse(icu::UnicodeString const&, int&, unsigned short, int, signed char, signed char, signed char*, icu::Calendar&) const
   7 libicucore.A.dylib  868.67 Kb     icu::SimpleDateFormat::parse(icu::UnicodeString const&, icu::Calendar&, icu::ParsePosition&) const
   8 libicucore.A.dylib  868.67 Kb     icu::DateFormat::parse(icu::UnicodeString const&, icu::ParsePosition&) const
   9 libicucore.A.dylib  868.67 Kb     udat_parse
  10 CoreFoundation  868.67 Kb     CFDateFormatterGetAbsoluteTimeFromString
  11 CoreFoundation  868.67 Kb     CFDateFormatterCreateDateFromString
  12 Foundation  868.67 Kb     -[NSDateFormatter getObjectValue:forString:range:error:]
  13 Foundation  868.75 Kb     -[NSDateFormatter getObjectValue:forString:errorDescription:]
  14 Foundation  868.75 Kb     -[NSDateFormatter dateFromString:]

谢谢!

3个回答

3
[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"]; // Remove the `z`

在 iPhone OS 2.2.1 或 3.1.2 (更多版本待测) 中,只要使用 "dateFromString" 并开启 z 选项,就会永久分配 868 KB 的内存。

可以阅读完整的文章、源代码和日志文件: http://thegothicparty.com/dev/article/nsdateformatter-memory-leak/


1

NSDateFormatter解析带有时区的日期字符串可能会出现问题,因为当我更改格式化程序模式以删除时区部分时,问题消失了。

我将其更改为:

[df setDateFormat:@"EEE, d MMM yyyy H:m:s z"];

To this:

[df setDateFormat:@"EEE, d MMM yyyy H:m:s"];

但现在的问题是日期没有得到正确的时区,所以我必须自己确定时区。

在Cocoa-dev邮件列表中有一个关于这个问题的讨论线程:http://lists.apple.com/archives/Cocoa-dev/2009/Apr/msg01913.html - IlDan

0

你说的舍弃NSDateFormatters是什么意思?你在使用完它们后是否会释放它们?

df = [[NSDateFormatter alloc] init]; // allocates memory

您的代码分配了内存,但您需要调用

[df release];

当你完成使用对象时,如果你分配(或复制)了该对象,则其引用计数会增加1。当你释放对象(发送release消息)时,引用计数会减少1。当引用计数达到0时,对象将被释放。

如果你不发送release消息,该对象将留在内存中,导致内存泄漏。


当我说我会放弃它们时,我指的是NSDate对象。从上面的堆栈跟踪中可以看出,我正在使用[NSDateFormatter dateFromString]来创建NSDate对象,从而导致malloc调用,这也在Instruments的最耗费堆栈跟踪中显示出来(顺便说一句,我已经为我发布的最耗费堆栈跟踪选择了“已创建并仍在运行”)。 - Cal
那就没有问题了,dateFromString会返回自动释放的对象。如果你创建了许多自动释放的NSDate对象,它们将一直存在,直到下一个事件循环,在那里它们将被清理。这是因为自动释放的对象最终会进入池中,在事件处理池的末尾进行清理,如果你创建了大量日期,这可能导致内存使用量增加。 - stefanB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接