0

我正在尝试将图像数据上传到服务器,它已成功上传,但每次上传图像时都会出现内存峰值。还上传了 20 多张图片,让 App 关闭并收到内存警告。 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];
4

3 回答 3

3

几个想法:

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

    例如,当我上传 20 次大约 5mb 的图像时,这是我的记忆,内存飙升至 113mb:

    在此处输入图像描述

    但是,如果我将其限制为一次只执行不超过 4 个(使用操作队列),则内存使用率会得到改善,最大为 55mb(即大约比基线高 38mb):

    在此处输入图像描述

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

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

    在此处输入图像描述

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

    我建议观看 WWDC 2013 视频Fixing Memory Issues或 WWDC 2012 视频iOS App Performance: Memory说明(除其他外)如何使用 Instruments 来识别内存问题。

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

    如果你必须使用UIImageJPEGRepresentation(例如它是一个程序创建的UIImage),那么就这样吧,做你必须做的。但是,如果您可以访问原始数字资产(例如,请参阅https://stackoverflow.com/a/27709329/1271826 ALAssetsLibrary,请执行此操作。可以在不使资产大于所需大小的情况下最大化质量。

最重要的是,您首先要确保没有任何内存泄漏,然后您希望在任何给定时间尽量减少内存中的内存量(NSData如果可以,不要使用任何内存)。

于 2015-04-09T18:00:36.273 回答
1

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

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

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

于 2015-04-08T12:39:21.793 回答
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];
        }
于 2015-04-08T12:46:13.383 回答