Загрузка данных UIImage на сервер с пиками памяти?

Я пытаюсь загрузить данные изображений на сервер, они успешно загружены, но получают пики памяти при каждой загрузке изображения. А также загрузка более 20 изображений, приводящих к закрытию приложения и предупреждению о нехватке памяти. Пики памяти данных UIImage

Как решить эту проблему?

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

Изменить: я использую 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];

person iamVishal16    schedule 08.04.2015    source источник
comment
Вы должны показать нам, как вы делаете загрузку. Если вы используете задачу загрузки NSURLSession либо с файлом, либо с потоком (а не с NSData), вы смягчите эту проблему. Суть в том, чтобы не загружать весь актив в память в любой момент времени.   -  person Rob    schedule 08.04.2015
comment
Как вы можете загрузить изображение? Можете ли вы разместить свой код здесь.   -  person Nimit Parekh    schedule 08.04.2015
comment
Кроме того, используйте инструмент распределения инструментов, а не датчики в Xcode. Это гораздо более точная мера того, что происходит на самом деле (плюс вы можете точно увидеть, что вызывает рост памяти).   -  person Rob    schedule 08.04.2015
comment
@NimitParekh Преобразование UIImage в NSData   -  person iamVishal16    schedule 08.04.2015
comment
@Vishu, пожалуйста, разместите здесь свой код, если это возможно.   -  person Nimit Parekh    schedule 08.04.2015
comment
Здравствуйте, ребята, почему я получаю отрицательные баллы в вопросе?   -  person iamVishal16    schedule 08.04.2015
comment
Потому что вы спрашиваете нас, как исправить ваш код, но не делитесь им с нами, несмотря на многочисленные просьбы. Вы должны показать нам, что вы делаете (или, лучше, MCVE). Используете ли вы NSURLConnection, NSURLSession, AFNetworking и т. д.? И, учитывая конкретную технологию, которую вы используете, как вы ее используете? Сейчас вы просто показываете нам симптомы проблемы, но не источник проблемы.   -  person Rob    schedule 08.04.2015
comment
@Vishu убедитесь, что ваш проект находится в режиме ARC.   -  person jigs    schedule 08.04.2015
comment
Мой проект поддерживает ARC?   -  person iamVishal16    schedule 08.04.2015
comment
Да, сначала сделайте это, и вы увидите, что 90% проблем с памятью будут решены.   -  person jigs    schedule 08.04.2015
comment
Я имею в виду, что в моем проекте уже включен ARC.   -  person iamVishal16    schedule 08.04.2015
comment
Хорошо.. теперь проверьте размер изображения, которое вы хотите загрузить. и попробуйте сначала сжать это изображение и загрузить это изображение.   -  person jigs    schedule 08.04.2015
comment
@Rob Я не хочу публиковать весь свой код. думаю не надо?   -  person iamVishal16    schedule 09.04.2015
comment
@Vishu Нет, определенно не публикуйте весь свой код. Как правило, вы хотите опубликовать минимум, чтобы люди могли воспроизвести описанное вами поведение (см. MCVE). Сейчас я думаю, что вы предоставленного достаточно, чтобы мы хотя бы поняли, что вы делаете (вручную создаете NSMutableURLRequest для составного запроса).   -  person Rob    schedule 09.04.2015


Ответы (3)


Пара мыслей:

  1. Если вы загружаете несколько изображений, вы можете ограничить их одновременное выполнение.

    Например, это моя память, когда я выдал 20 загрузок примерно по 5 МБ на изображение, память увеличилась до 113 МБ:

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

    Если, однако, я ограничил это только выполнением не более 4 операций за раз (используя очереди операций), использование памяти улучшилось, максимально достигнув 55 МБ (т.е. примерно на 38 МБ по сравнению с базовым уровнем):

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

    Другие предполагают, что вы могли бы подумать о том, чтобы не выполнять более одной загрузки за раз, и это еще больше снижает пиковое использование памяти (в моем примере пиковое использование памяти составляло 27 МБ, всего на 10 МБ по сравнению с базовым уровнем), но признайте, что вы платите серьезные штраф за производительность за это.

  2. При использовании NSURLSession, если вы используете задачу загрузки с параметром fromFile, а не загружаете актив в NSData, даже при одновременном выполнении 4 он использует значительно меньше памяти, менее 1 МБ по сравнению с базовым планом:

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

  3. Я заметил, что вы используете датчики Xcode для анализа использования памяти. Я бы предложил использовать инструмент «Распределение инструментов» (как показано выше). Причина, по которой я предлагаю это, заключается не только в том, что я считаю это более точным, но, что более важно, у вас, кажется, есть некоторый образец памяти, который не полностью возвращается к исходному уровню после выполнения некоторых действий. Это говорит о том, что у вас могут быть утечки. И только Инструменты помогут вам выявить эти утечки.

    Я бы посоветовал посмотреть видео WWDC 2013 Исправление проблем с памятью или WWDC Видео 2012 г. Производительность приложения iOS: память, иллюстрирующее (среди прочего) ) как использовать Инструменты для выявления проблем с памятью.

  4. Я заметил, что вы извлекаете NSData из UIImage объектов. Я не знаю, как вы получаете изображения, но если они из вашего ALAssetsLibrary (или если вы загрузили их с другого ресурса), вы можете захотеть получить исходный ресурс, а не загружать его в UIImage, а затем создавать NSData от этого. Если вы используете UIImageJPEGRepresentation, вы неизменно либо (а) делаете NSData больше исходного актива (усугубляя проблему с памятью); или (б) снизить качество без необходимости, чтобы уменьшить NSData. Кроме того, вы удаляете большую часть метаданных.

    Если вам нужно использовать UIImageJPEGRepresentation (например, это программно созданный UIImage), то так тому и быть, делайте то, что должны делать. Но если у вас есть доступ к исходному цифровому активу (например, см. https://stackoverflow.com/a/27709329/1271826 для примера ALAssetsLibrary), затем сделайте это. Качество можно максимизировать, не увеличивая актив больше, чем он должен быть.

Суть в том, что вы сначала хотите убедиться, что у вас нет утечек памяти, а затем вы хотите свести к минимуму объем памяти, который вы держите в памяти в любой момент времени (не используя NSData, если можете).

person Rob    schedule 09.04.2015
comment
Спасибо, очень хорошее объяснение. - person iamVishal16; 10.04.2015
comment
Мысль номер 2 значительно уменьшила использование моей памяти. Спасибо! - person A.Andino; 25.02.2020

Пики памяти безвредны. Вы получите их, когда будете выполнять тяжелые загрузки и загрузки. Но позже он должен вернуться к своему нормальному уровню, как это имеет место на изображении, которое вы разместили. Так что я чувствую, что это безвредно и очевидно в вашем случае.

Вы должны беспокоиться только тогда, когда ваше приложение использует память и не освобождает ее позже...

Если вы выполняете тяжелую загрузку... посмотрите ответ в эта тема.

person Mayur Deshmukh    schedule 08.04.2015
comment
но мое приложение закрывается, когда я пытаюсь загрузить более 20 изображений? - person iamVishal16; 08.04.2015
comment
Вы отправляете их все в одном запросе? Если нет, я попрошу вас опубликовать наш код загрузки - person Mayur Deshmukh; 08.04.2015
comment
Да, я отправляю их всех в одном запросе? - person iamVishal16; 08.04.2015
comment
Вы используете NSURLSession? - person Mayur Deshmukh; 08.04.2015
comment
Нет, я не использую NSURLSession? - person iamVishal16; 08.04.2015
comment
Тогда я бы посоветовал вам переключиться на NSURLSession. И, если возможно, загружайте изображения по очереди. Также проверьте отредактированный ответ для ссылки, которая поможет вам в ваших тяжелых загрузках. - person Mayur Deshmukh; 08.04.2015

Можете ли вы показать свой код? Вы пробовали с 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];
        }
person davidosorio    schedule 08.04.2015
comment
Это только для одного файла или для нескольких? - person iamVishal16; 08.04.2015
comment
Это только для одного файла, но вы можете положить код в букле - person davidosorio; 08.04.2015