XCode 4 + Instruments 4:虚警泄漏?

6
自从我使用XCode 4之后,泄漏工具显示有很多泄漏,都是来自JSONKit和ASIHTTPRequest的。在运行了2分钟之后,我泄漏了数百个数组/字典/字符串(来自jk_create_dictionary、jk_parse_array、HTTPMessage::*等),总共几百KB。大部分堆栈跟踪并不起源于我的任何调用,其余的则完全无辜。 我非常确定这在XCode 4之前不是这样的。 我不知道罪魁祸首是谁。任何见解都将不胜感激。
更新: JSONKit泄漏可能是由于JSONDecoder缓存导致的。 例如:
static JSONDecoder *decoder = nil;
if (!decoder) 
    decoder=[[JSONDecoder alloc] init];

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
[request setCachePolicy:ASIDoNotWriteToCacheCachePolicy];
[request setCompletionBlock:^{
    NSData *response = [request responseData];
    NSDictionary *json = [decoder objectWithUTF8String:[response bytes] length:[response length]];
    // ...
}];
[request setFailedBlock:^{
    // ...
}];

[request startAsynchronous];

也收到了使用JSONKit的泄漏报告...正在调查中。 - Vincent Guerci
JSONKit 工作得非常完美,在你的情况下是你的代码(我猜可能使用了 block)导致了内存泄漏。也许你应该编辑你的问题或接受一个答案来关闭这个问题。 - Vincent Guerci
2个回答

2

编辑:在您阅读本答案的其余部分之前:

如果您看到那种内存泄漏,请不要责怪Instruments或JSONKit...两者都是可靠的!

...该责任在于您自己,99.9%的几率是因为您的代码泄漏了使用JSONKit解析的数据!

结束编辑


这不是一个回答,而是一种补充,并试图理解发生了什么,因为我也在Instruments中看到了内存泄漏。

我是这样使用JSONKit的:

NSArray *lines = [dataString componentsSeparatedByString:@"\n"];
for (NSString *line in lines) { // I know, strange format isn't? :)
  NSDictionary *json = [line objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
  // use dictionary data...
}

@ssteinberg,您遇到的是这种泄漏问题吗?:JSONKitLeaks

请注意,我在进行了一些重载测试后才出现了这个问题,500个请求带有巨大的JSON响应,这解释了泄漏量为MB(使用最新的gh版本) (using latest gh version)

请注意,我对使用Instruments还很陌生,不确定如何理解这些结果。根据报告的框架,是缓存...但我想要确认一下...

所以我在GH上开了一个问题,希望@johnezang或其他人能给我们提供更多信息。

如果这只是Instruments的误解,那么我向大家道歉 :)


是的,这就是我所拥有的。在升级到最终版Xcode 4.0.1(4A1006)后,我不再有任何泄漏了。不知道为什么。可能是苹果方面的问题,也可能是我在最近两个版本(2周时间足够了)之间更改的代码。我不知道。如果您的代码是从块内调用的,请确保它被正确释放,否则我就不知道了。耸肩 - unexpectedvalue
感谢@johnezang指出我的代码(以及显然是我)很愚蠢,结论是:1. Instruments是正确的;2. 我不知道如何阅读Instruments报告;3. JSONKit是由一个非常有技巧的人编写的,他高度优化了他的代码。使用其他JSON解析器的人真的应该看一看! - Vincent Guerci

0
根据苹果公司2010年WWDC视频(使用Instruments进行高级内存分析),误报的泄漏很少见。有时候Leaks工具会错过泄漏,但它对报告的泄漏是可靠的。我不太擅长静态分析,但你是否已经检查过确保没有在未释放的情况下分配解码器?如果它没有被释放并且超出了范围,那就构成了一个泄漏,对吧?

ASIHTTP工作线程中发生的ASIHHTPRequest泄漏问题,我没有堆栈跟踪,只有一个或两个方法。稍后我会发布更多信息。至于JSONKit,解码器是静态的,因为我可能每秒钟调用一次它,但即使尝试非静态和释放解码器也没有什么改变。我想解码器进行了一些缓存,这被计算为泄漏,因为JSONKit提供了出色的性能。 - unexpectedvalue

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