我正在开发一个从API下载和解析大约40k json文件的应用程序。由于我的程序结构,我不会立即解析它们,而是将它们保存在NSMutable数组中。每个json大约1KB,大多数甚至更少。如果我的计算是正确的,那应该会产生大约40MB(+一些开销)的已分配内存。但是当我运行应用程序时,内存使用率攀升至4GB以上。
我在这里泄漏了什么吗?既然我使用垃圾收集,我不需要解除任何东西,对吧?或者我的计算错了?
这是我的代码:
- (void) loadItemsForIds:(NSArray*)idList {
for (NSNumber* n in idList) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://someapi.com/somejson.json?id=%@", n]];
NSData* response = [NSData dataWithContentsOfURL:url];
NSDictionary *loadedData = [NSJSONSerialization JSONObjectWithData:response options:0 error:nil];
@synchronized(self.updateData) {
[self.updateData addObject:loadedData];
}
[self performSelectorOnMainThread:@selector(progressLoadingInterface:) withObject:[loadedData valueForKey:@"name"] waitUntilDone:NO];
};
}
编辑:
如果我不将数据保存到数组中,则发现问题甚至存在。在经过一些研究之后,我偶然发现了一个处理同样问题的问题:iPhone - Memory Leak - NSData dataWithContentsOfUrl & UIWebView
我的问题可能需要删除。
答案 0 :(得分:0)
[NSJSONSerialization JSONObjectWithData:response options:0 error:nil]
将JSON数据解析为对象。这将占用比1K JSON数据更多的内存。
此外,NSString
可能将所有字符串数据存储为unichar
,这是一个16位表示:是JSON数据中假设的UTF-8编码大小的两倍。
根据JSON的内容,我可以相信1K的JSON数据可能会成为10K的对象。
但这都是猜测工作。使用Instruments(Product> Profile)检查内存使用情况。这将使您更好地了解哪些对象占用了所有内存。
答案 1 :(得分:0)
你永远不会在40k迭代之间释放内存 =>你永远不会给任何人这样做的机会(arc / gc)
将循环 body 包裹在@autoreleasepool {...}
中,以便耗尽内存
for (NSNumber* n in idList) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://someapi.com/somejson.json?id=%@", n]];
NSData* response = [NSData dataWithContentsOfURL:url];
NSDictionary *loadedData = [NSJSONSerialization JSONObjectWithData:response options:0 error:nil];
@synchronized(self.updateData) {
[self.updateData addObject:loadedData];
}
[self performSelectorOnMainThread:@selector(progressLoadingInterface:) withObject:[loadedData valueForKey:@"name"] waitUntilDone:NO];
}
}