【问题标题】:High memory usage when parsing JSON解析 JSON 时内存使用率高
【发布时间】:2015-07-28 15:23:00
【问题描述】:

我目前正在从 JSON 解析我的所有数据并将其存储在一个数组中。然而,当它开始解析时,内存使用量从大约 25mb 跃升至 800mb。在做了一些研究之后,我被告知在 GCD 块中放置一个 @autoreleasepool 但无济于事。

这是我目前得到的代码:

 self.channelSchedules = [NSMutableArray new];
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //Loop through each channel object and download schedule
    @autoreleasepool {
        for (atlas_channel* channel in self.channels) {
            NSLog(@"Updating listings for %@", [channel getChannelTitle]);
            [self.channelSchedules addObject:[[channel getChannelSchedule] returnCurrentContentObject]];
            [self.tableView reloadData];
            [self scrollViewDidScroll:nil];
        }
    }
    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
        [self.tableView reloadData];
    });
});

我正在使用 TouchJSON 来解析数据。

经过进一步的研究,我认为这与我将所有值一旦解析成一个 NSArray 就将其存储在内存中的事实有关。我想我将不得不使用 CoreData 或类似的东西。

【问题讨论】:

  • 如果您的 autoreleasepool 在 for 循环内,您将在每次迭代中得到耗尽。可能有更好的方法来设计此代码以避免内存,但这可能是一个快速修复。
  • 它已减半至约 400mb。不过,这似乎仍然很高
  • 你要解析多少数据? @autoreleasepool 在这里没用(你的整个应用不都在@autoreleasepool 下吗?)
  • 我正在解析一个 JSON 文件,然后对于返回的每个条目,我必须解析另外两个 JSON 文件。这是因为 atlas 的工作方式。我正在使用 metabroadcast 中的 Atlas API。

标签: objective-c json memory-management memory-leaks touchjson


【解决方案1】:

只在 mainThread 上调用 [self.tableView reloadData]。

【讨论】:

  • 不幸的是,这似乎对内存问题没有帮助。
【解决方案2】:
  1. 您是否同时从两个线程访问同一个可变数组?那将无法可靠地工作。

  2. 正如其他人所说,不要从后台线程更新表。

  3. JSON 文件有多大?您实际上是以一种效率较低的方式将所有数据存储在 RAM 中,因此预计内存使用量是原始文本的两倍。

  4. 试试 Apple 的 JSON 解析器。

【讨论】:

  • 1.是的,虽然我正在考虑从使用数组切换到核心数据或类似的东西。 2. 我现在已经删除了。 3. 每个 JSON 文件大约 0.14mb,这几乎没有什么,但我必须下载大约 400-450 个这些文件。 4. 一开始我用的是苹果的 JSON 解析器,但是每次有 nil 对象时它都会崩溃,所以我切换了。
  • 除非您一次需要所有已解码的数据,否则最好将 400 个文件存储在 Documents 或 Cache 目录中并根据需要对其进行解码。
  • 这就是我现在正在做的事情。我将使用 Core Data 存储数据。我会报告进展情况。
【解决方案3】:

高内存使用是因为我将 JSON 项存储在一个 NSArray 中,该 NSArray 将自身保留在内存中。我可以通过使用领域将我的对象缓存到磁盘并在需要时像 EricS 建议的那样调用它们来解决这个问题。该应用程序现在最多使用 32mb,这要好得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    相关资源
    最近更新 更多