4
votes

So I have a memory problem with my app. The app has a MKMapView with MKOverlayRenderer which loads images on the map. Everything working ok but after 30-60 minutes the app crashes due memory.

With Instruments I found that NSURLConnection is growing and because I cannot find anything else (besides all kind of stuff I dont understand) I think thats is my problem.

Screenshot instruments after runnning for 1-2 minutes:

instruments NSURLConnection

Screenshot instruments after running for 12-13 minutes: instruments after 12-13 minutes

Images are loaded like this in the canDrawMapRect method and saved to tmp folder (if I turn this off the NSURLConnection won't grow that high):

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[OperationQueues sharedOperationQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {


                               [data writeToFile:path atomically:YES];

Then loaded in the drawMapRect method.

I tried fixing this with the following code:

AppDelegate:

int cacheSizeMemory = 4*1024*1024; // 4MB
int cacheSizeDisk = 32*1024*1024; // 32MB
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory
                                                     diskCapacity:cacheSizeDisk
                                                         diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];

ViewController:

- (void)didReceiveMemoryWarning
{
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [super didReceiveMemoryWarning];
}

right after the request: [added]

[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];

But as you can see in Instruments without any luck.

  1. Could this be my problem?
  2. Is this the NSURLCache which is growing or something else?

As requested a couple more screenshots from instruments:

statisticsenter image description here

1
Could you open the call tree by clicking the triangle next to +[NSURLConnection _resourceLoadLoop]?thelaws
Also, what makes you think this is related to NSURLCache?thelaws
In addition to the "call tree" view, can you show us the "statistics" page? I also assume that you do not have zombies turned on (because that will prevent memory from being entirely released)? My standard approach would be to focus on "statistics" page, make sure that "record reference counts" is turned on in Instruments, find objects of mine that should be released but aren't, and then drill into the reference counts details to figure out where the object's (incorrect) strong references are.Rob
TX! Screens added. I think it's NSURLCache because I couldn't think of something else, if I comment out the NSURLConnection there the memory of NSURLConnection isnt growing. Zombies is indeed turned off, it's hard to understand the statistics page for me. Record reference counts is on.Sjoerd Perfors
How many network requests are made/how often is canDrawMapRect called? To really test the NSURLCache you should set the cacheSize to 0. (Also, in your code snippet, you only need to setSharedURLCache once)thelaws

1 Answers

2
votes

First, 400 network requests in one minute seems pretty excessive. Some of those requests are probably duplicated or unnecessary. The amount of calls is obviously downloading a lot of information, and not giving the os much time to cleanup.

Second, your NSURLCache is actually providing more memory space than the default cache. I tested on my device/simulator and ios provides a default memory capacity of 512 000 bytes. You're caches are initialized with 4 194 304 bytes (and way more on disk).

I would suggest that you set your cache size smaller to see some improvement. However, investigating the amount of network requests that are made will provide longer term benefits.