Jeff Ogata
Jeff Ogata

Reputation: 57783

Memory problems with large JSON data

My company has created a web service that is used by an iPad app, and having no iOS development experience in house, we contracted out that work.

As part of an initialization process, the app receives a starting set of data from the web service, in JSON format. For most app users, this data set will be approximately 4 MB in size (uncompressed), and the app handles this without problems.

For a smaller group of users, the data size is much larger, approximately 65 MB uncompressed. With this data set, the iPad app crashes, and the developers have claimed that the app is being killed because it is using too much memory. If I understand them correctly, they are saying that this is happening while trying to parse the JSON into in-memory objects.

My feeling is that a device with 1 GB of memory should not have problems processing 65 MB of data, but I have no experience with the iOS environment to base this on.

Has anyone been able to process large sets of JSON data in iOS? If the problem is with loading the entire JSON data set in memory, is there a streaming JSON parser for iOS that would use less memory?

Upvotes: 2

Views: 2413

Answers (1)

Nico
Nico

Reputation: 3826

I don't believe the issue is with converting json into NSDictionaries/ NSArrays / NSStrings / NSNumbers.

My guess would be that you are using the result of the json with autoreleased objects in a tight loop, such as creating thumbnails for all images before the autoreleased pool is emptied.

If they doesn't not fit what your data is doing, can you give us some example as to what type of work is being done on the data set?

This is very bad code because it will continue to stack umcompressed uiimages into the autorelease pool which won't be hit until all the images have been downloaded and made into thumbnails.

NSArray* images = [jsonObject objectForKey:@"images"];

for(NSString* imageURL in images){
    NSURL* url = [NSURL URLWithString: imageURL];
    NSData* data = [NSData dataWithContentsOfURL: url];
    UIImage* image = [UIImage imageWithData: data];
    // write image to disk
    UIImage* thumbnail = CreateThumbnailFromImage(image);
    // write thumbnail to disk
}

The same code can be fixed by adding in another autorelease pool that will clean up the autoreleased objects sooner.

for(NSString* imageURL in images){
    @autoreleasepool {
    NSURL* url = [NSURL URLWithString: imageURL];
    NSData* data = [NSData dataWithContentsOfURL: url];
    UIImage* image = [UIImage imageWithData: data];
    // write image to disk
    UIImage* thumbnail = CreateThumbnailFromImage(image);
    // write thumbnail to disk
    }
}

Upvotes: 1

Related Questions