NSURLConnection растет в инструментах, это NSURLCache?

Итак, у меня проблема с памятью в моем приложении. Приложение имеет MKMapView с MKOverlayRenderer, который загружает изображения на карту. Все работает нормально, но через 30-60 минут приложение вылетает из-за памяти.

С инструментами я обнаружил, что NSURLConnection растет, и, поскольку я не могу найти ничего другого (кроме всего, что я не понимаю), я думаю, что это моя проблема.

Скриншот инструментов после запуска в течение 1-2 минут:

инструменты NSURLConnection

Скриншот приборов после 12-13 минут работы: приборы через 12-13 минут

Изображения загружаются таким образом в методе canDrawMapRect и сохраняются в папку tmp (если я отключу это, NSURLConnection не будет расти так высоко):

    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];

Затем загружается в метод drawMapRect.

Я попытался исправить это с помощью следующего кода:

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];

Вьюконтроллер:

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

сразу после запроса: [добавлено]

[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];

Но, как вы можете видеть в Инструментах, безуспешно.

  1. Может ли это быть моей проблемой?
  2. Это NSURLCache, который растет, или что-то еще?

По просьбе еще пара скринов с приборов:

статистикавведите описание изображения здесь


person Sjoerd Perfors    schedule 22.12.2014    source источник
comment
Не могли бы вы открыть дерево вызовов, щелкнув треугольник рядом с +[NSURLConnection _resourceLoadLoop]?   -  person thelaws    schedule 23.12.2014
comment
Кроме того, что заставляет вас думать, что это связано с NSURLCache?   -  person thelaws    schedule 23.12.2014
comment
В дополнение к просмотру дерева вызовов, вы можете показать нам страницу статистики? Я также предполагаю, что у вас не включены зомби (потому что это предотвратит полное освобождение памяти)? Мой стандартный подход заключается в том, чтобы сосредоточиться на странице статистики, убедиться, что счетчики ссылок на записи включены в «Инструменты», найти мои объекты, которые должны быть выпущены, но не выпущены, а затем углубиться в детали счетчиков ссылок, чтобы выяснить, где находится объект. (неправильно) сильные ссылки.   -  person Rob    schedule 23.12.2014
comment
Техас! Добавлены экраны. Я думаю, что это NSURLCache, потому что я не мог придумать что-то еще, если я закомментирую NSURLConnection, память NSURLConnection не увеличивается. Зомби действительно отключены, мне сложно понять страницу статистики. Подсчет ссылок на записи включен.   -  person Sjoerd Perfors    schedule 23.12.2014
comment
Сколько сетевых запросов сделано/как часто вызывается canDrawMapRect? Чтобы действительно протестировать NSURLCache, вы должны установить cacheSize равным 0. (Кроме того, в вашем фрагменте кода вам нужно только setSharedURLCache один раз)   -  person thelaws    schedule 23.12.2014
comment
около 400 раз в первую минуту, во вторую минуту еще 350. Но я издеваюсь над своим местоположением, и оно быстро меняется, поэтому в реальном мире это было бы меньше. Я установил его на ноль и удалил другой. Ничего себе, wtf думает, что это сделало!, я тестирую это еще пару раз!   -  person Sjoerd Perfors    schedule 23.12.2014


Ответы (1)


Во-первых, 400 сетевых запросов в минуту кажутся чрезмерными. Некоторые из этих запросов, вероятно, дублируются или не нужны. Количество вызовов, очевидно, загружает много информации и не дает ОС много времени на очистку.

Во-вторых, ваш NSURLCache на самом деле предоставляет больше места в памяти, чем кеш по умолчанию. Я тестировал на своем устройстве/симуляторе, и ios обеспечивает объем памяти по умолчанию 512 000 байт. Ваши кеши инициализируются 4 194 304 байтами (и намного больше на диске).

Я бы посоветовал вам уменьшить размер кеша, чтобы увидеть некоторое улучшение. Однако исследование количества сделанных сетевых запросов обеспечит более долгосрочные преимущества.

person thelaws    schedule 23.12.2014
comment
Спасибо, что указали на 400 запросов, я кое-что выяснил: использование MKMapCamera с наклоном приводит к таким большим суммам, потому что для каждого уровня масштабирования требуется изображение, а с наклоном вы видите карту в diff. уровни масштабирования. Сейчас без 3D намного меньше. Кроме того, у меня было кэширование файлов на 1 секунду, чтобы как можно быстрее воспроизвести ошибку, поэтому 400 не было фактическим числом в производстве. Теперь это 500 запросов в течение 5 минут при движении со скоростью 100 м/с (360 км/ч). Первое приближение карты к локациям вызывает уже 100 запросов. - person Sjoerd Perfors; 23.12.2014