iamVishal16
iamVishal16

Reputation: 1780

Uploading UIImage data to the server getting memory peaks?

I am trying to upload images data to the server, it uploaded successfully, but getting memory peaks on per image upload. And also uploading more than 20 images getting App shut's down and receiving memory warnings. UIImage data memory peaks

How to resolve this issue?

enter image description here

Edit: I am using 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];

Upvotes: 0

Views: 1245

Answers (3)

Rob
Rob

Reputation: 437917

A couple of thoughts:

  1. If uploading multiple images, you might want to constrain how many you perform concurrently.

    For example, this is my memory when I issued 20 uploads of roughly 5mb per image, memory spiked up to 113 mb:

    enter image description here

    If, however, I constrained this to only doing no more than 4 at a time (using operation queues), the memory usage was improved, maxing out at 55mb (i.e. roughly 38mb over baseline):

    enter image description here

    Others have suggested that you might consider not doing more than one upload at a time, and that further reduces the peak memory usage further (in my example, peak memory usage was 27mb, only 10mb over baseline), but recognize that you pay a serious performance penalty for that.

  2. If using NSURLSession, if you use at upload task with the fromFile option rather than loading the asset into a NSData, even when doing 4 concurrently it used dramatically less memory, less than 1 mb over baseline:

    enter image description here

  3. I notice that you're using the Xcode gauges to analyze memory usage. I'd suggest using Instruments' Allocations tool (as shown above). The reason I suggest this is not only do I believe it to be more accurate, but more importantly, you seem to have some pattern of memory not falling completely back down to your baseline after performing some actions. This suggests that you might have some leaks. And only Instruments will help you identifying these leaks.

    I'd suggest watching WWDC 2013 video Fixing Memory Issues or WWDC 2012 video iOS App Performance: Memory which illustrate (amongst other things) how to use Instruments to identify memory problems.

  4. I notice that you're extracting the NSData from the UIImage objects. I don't know how you're getting the images, but if they're from your ALAssetsLibrary (or if you downloaded them from another resource), you might want to grab the original asset rather than loading it into a UIImage and then creating a NSData from that. If you use UIImageJPEGRepresentation, you invariably either (a) make the NSData larger than the original asset (making the memory issue worse); or (b) reduce the quality unnecessarily in an effort to make the NSData smaller. Plus you strip out much of the meta data.

    If you have to use UIImageJPEGRepresentation (e.g. it's a programmatically created UIImage), then so be it, do what you have to do. But if you have access to the original digital asset (e.g. see https://stackoverflow.com/a/27709329/1271826 for ALAssetsLibrary example), then do that. Quality may be maximized without making the asset larger than it needs to be.

Bottom line, you first want to make sure that you don't have any memory leaks, and then you want to minimize how much you hold in memory at any given time (not using any NSData if you can).

Upvotes: 3

davidosorio
davidosorio

Reputation: 56

Can you show your code ? Have you tried with NSURLSession ? I don't have problems with the memory if I upload photos with 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];
        }

Upvotes: 0

Mayur Deshmukh
Mayur Deshmukh

Reputation: 1169

Memory peaks are harmless. You are going to get them when you are performing heavy uploads and downloads. But it should go back to its normal level later on, which is the case in the image you have posted. So i feel it is harmless and obvious in your case.

You should only worry when your application uses memory and doesnt release it later...

If you are performing heavy upload.. have a look at answer in this thread.

Upvotes: 1

Related Questions