Загрузка данных UIImage на сервер, получая пики памяти?
Я пытаюсь загрузить данные изображений на сервер, они были успешно загружены, но при каждой загрузке изображений возникают пики памяти. А также загружать более 20 изображений, отключая приложение и получая предупреждения о памяти.
Как решить эту проблему?
Изменить: я использую NSURLConnection.
image = [params valueForKey:key];
partData = UIImageJPEGRepresentation([ImageUtility getQualityFilterImage:[params valueForKey:key]], 0.8f);
if([partData isKindOfClass:[NSString class]])
partData=[((NSString*)partData) dataUsingEncoding:NSUTF8StringEncoding];
[body appendData:partData];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[urlRequest setHTTPBody:body];
3 ответа
Пара мыслей:
При загрузке нескольких изображений вы можете ограничить количество одновременных выступлений.
Например, это моя память, когда я выпустил 20 загрузок примерно по 5 МБ на изображение, объем памяти увеличился до 113 МБ:
Если, однако, я ограничил это только выполнением не более 4 за раз (с использованием очередей операций), использование памяти было улучшено, максимально до 55 МБ (т.е. примерно 38 МБ по сравнению с базовым уровнем):
Другие полагают, что вы можете подумать не делать более одной загрузки за раз, и это еще больше снижает пиковое использование памяти (в моем примере пиковое использование памяти было 27 МБ, только 10 МБ по сравнению с базовой линией), но признаете, что вы платите серьезную штраф за производительность.
При использовании
NSURLSession
, если вы используете при загрузке задачи сfromFile
вариант, а не загрузка актива вNSData
даже при одновременном выполнении 4 он использовал значительно меньше памяти, менее 1 мегабайта по сравнению с базовым уровнем:Я заметил, что вы используете датчики XCode для анализа использования памяти. Я бы предложил использовать инструмент Распределения инструментов (как показано выше). Причина, по которой я предлагаю это, заключается не только в том, что я считаю, что это более точно, но, что более важно, у вас, кажется, есть некоторый паттерн памяти, который не полностью возвращается к вашей базовой линии после выполнения некоторых действий. Это говорит о том, что у вас могут быть некоторые утечки. И только инструменты помогут вам выявить эти утечки.
Я бы посоветовал посмотреть видео WWDC 2013 " Исправление проблем с памятью" или видео WWDC 2012 " iOS". Производительность приложения iOS: память, которая иллюстрирует (среди прочего), как использовать инструменты для выявления проблем с памятью.
Я заметил, что вы извлекаете
NSData
отUIImage
объекты. Я не знаю, как вы получаете изображения, но если они из вашегоALAssetsLibrary
(или если вы загрузили их с другого ресурса), вы можете получить исходный ресурс, а не загружать его вUIImage
а затем созданиеNSData
От этого. Если вы используетеUIImageJPEGRepresentation
Вы неизменно либо (а) делаетеNSData
больше, чем исходный ресурс (что усугубляет проблему с памятью); или (б) необоснованно снижать качество, чтобыNSData
меньше. Кроме того, вы удаляете большую часть метаданных.Если вы должны использовать
UIImageJPEGRepresentation
(например, это программно созданныйUIImage
), пусть будет так, делай то, что должен. Но если у вас есть доступ к оригинальному цифровому ресурсу (например, см. /questions/21231508/zagruzka-izobrazheniya-s-pomoschyu-prilozheniya-ios-na-server-slishkom-velika/21231512#21231512 дляALAssetsLibrary
пример), то сделай это. Качество можно максимизировать, не увеличивая активы до необходимого уровня.
В итоге, вы сначала хотите убедиться, что у вас нет утечек памяти, а затем вы хотите минимизировать, сколько вы держите в памяти в любой момент времени (не используя какие-либо NSData
если ты можешь).
Пики памяти безвредны. Вы получите их, когда выполняете тяжелые загрузки и скачивания. Но позже он должен вернуться к своему нормальному уровню, как на изображении, которое вы опубликовали. Так что я чувствую, что это безопасно и очевидно в вашем случае.
Вам следует беспокоиться только тогда, когда ваше приложение использует память и не освобождает ее позже...
Если вы выполняете тяжелую загрузку.. посмотрите ответ в этой теме.
Вы можете показать свой код? Вы пробовали с NSURLSession? У меня нет проблем с памятью, если я загружаю фотографии с NSURLSession.
NSURL *url = [NSURL URLWithString:@"SERVER"];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
for (UIImage *image in self.arrayImages) {
UIImage *imageToUPload = image;
NSData *data = UIImagePNGRepresentation(imageToUPload);
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:[NSURLRequest requestWithURL:url] fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
[task resume];
}