将UIImage数据上传到服务器获取内存峰值?

时间:2015-04-08 12:33:54

标签: ios objective-c xcode uiimage memory-pressure

我正在尝试将图片数据上传到服务器,上传成功,但每张图片上传时内存达到峰值。此外,还上传了20多张图片,让App关闭并收到内存警告。 UIImage data memory peaks

如何解决此问题?

enter image description here

修改 我正在使用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 个答案:

答案 0 :(得分:2)

有几点想法:

  1. 如果要上传多张图片,您可能需要约束同时执行的图像数量。

    例如,这是我的记忆,当我发布20张每张图片大约5mb的内容时,内存飙升至113 MB:

    enter image description here

    但是,如果我将此限制为一次不超过4次(使用操作队列),则内存使用量会有所改善,最大值为55mb(即基线大约为38mb):

    enter image description here

    其他人建议您可以考虑一次不要进行多次上传,这进一步降低了峰值内存使用量(在我的示例中,峰值内存使用量为27mb,仅超过基线10mb),但认识到你为此付出严重的性能损失。

  2. 如果使用NSURLSession,如果您在上传任务时使用fromFile选项,而不是将资产加载到NSData,即使同时执行4次,也会大大减少使用NSData内存,比基线小不到1 MB:

    enter image description here

  3. 我注意到您正在使用Xcode仪表来分析内存使用情况。我建议使用Instruments的Allocations工具(如上所示)。我建议这样做的原因不仅是我认为它更准确,更重要的是,你似乎有一些记忆模式在执行某些动作后没有完全回落到你的基线。这表明您可能有一些泄漏。只有仪器才能帮助您识别这些泄漏。

    我建议观看WWDC 2013视频Fixing Memory Issues或WWDC 2012视频iOS App Performance: Memory,其中说明了(如此)如何使用工具识别内存问题。

  4. 我注意到您从UIImage对象中提取ALAssetsLibrary。我不知道你是如何获取图像的,但是如果它们来自你的UIImage(或者你是从其他资源下载的那些),你可能想要获取原始资产而不是将其加载到NSData然后从中创建UIImageJPEGRepresentation。如果您使用NSData,则总是要么(a)使NSData大于原始资产(使内存问题更严重);或(b)不必要地降低质量,以使UIImageJPEGRepresentation更小。此外,您还要删除大部分元数据。

    如果你必须使用UIImage(例如,它是以编程方式创建的ALAssetsLibrary),那么就这样吧,做你必须做的事情。但是,如果您有权访问原始数字资产(例如,请参阅NSData以获取{{1}}示例),那么请执行此操作。在不使资产大于其需要的情况下,可以最大化质量。

  5. 最重要的是,您首先要确保没有任何内存泄漏,然后您希望在任何给定时间最小化内存容量(如果可以的话,不要使用任何{{1}} )。

答案 1 :(得分:1)

内存峰值无害。当您执行繁重的上传和下载时,您将获得它们。但它应该会在以后恢复到正常水平,就像你发布的图像一样。所以我认为在你的情况下它是无害的和明显的。

您应该只在应用程序使用内存时才会担心,并且以后不会释放它...

如果您正在执行大量上传..请查看this thread中的答案。

答案 2 :(得分:0)

你能展示你的代码吗?你尝试过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];
        }