当前位置: 首页 > news >正文

济南网站开发销售系统

济南网站开发,销售系统,工厂找订单哪个平台最好,甘肃网站建设费用问题: 即时通讯App在发送图片消息时内存暴涨导致网络请求初始化失败(内存不足OOM),发送消息失败。 可能原因分析: 有内存泄漏。发送的图片消息,可能包含大图,没有进行压缩处理,导致…

问题:

即时通讯App在发送图片消息时内存暴涨导致网络请求初始化失败(内存不足OOM),发送消息失败。

可能原因分析:

  1. 有内存泄漏。
  2. 发送的图片消息,可能包含大图,没有进行压缩处理,导致内存占用过高。
  3. 在发送过程中,可能同时进行了图片的读取和处理,如果图片很大,处理过程中会产生很大的内存峰值。

解决方案:

  1. 对于发送消息时的内存暴涨:
  • 检查是否有内存泄漏,使用Instruments工具检测。

Instruments工具检测结果

检测发现确实有内存泄漏,解决后发现问题还是存在。

  • 在发送图片消息前,对图片进行压缩(包括压缩质量和尺寸),然后再发送压缩后的图片。

  • 避免直接操作大图,可以使用后台线程进行处理,防止阻塞主线程。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 1. 读取图片(避免使用imageNamed:)UIImage *originalImage = [UIImage imageWithContentsOfFile:filePath];// 2. 尺寸压缩(限制最大边长为1024)CGFloat maxSize = 1024.0;CGSize scaledSize = [self scaledSizeForImage:originalImage maxLength:maxSize];// 3. 质量压缩(70%质量)UIImage *compressedImage = [self resizeImage:originalImage toSize:scaledSize];NSData *imageData = UIImageJPEGRepresentation(compressedImage, 0.7);// 4. 发送压缩后的数据(非原始图片)[self sendImageData:imageData];
});// 计算缩放尺寸
- (CGSize)scaledSizeForImage:(UIImage *)image maxLength:(CGFloat)maxLength {CGFloat ratio = MIN(maxLength / image.size.width, maxLength / image.size.height);return CGSizeMake(image.size.width * ratio, image.size.height * ratio);
}// 图片重绘
- (UIImage *)resizeImage:(UIImage *)image toSize:(CGSize)targetSize {UIGraphicsBeginImageContextWithOptions(targetSize, NO, UIScreen.mainScreen.scale);[image drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return resizedImage;
}
  • 压缩后的图片数据要及时释放不必要的资源,避免在内存中同时存在多张图片,比如在图片展示后,如果原图不再需要,可以将其置为nil,帮助内存回收。(@autoreleasepool)。

处理到此内存暴涨解决了,但是随着发送图片内存还是在持续增加,现在每发送一张图片内存还是要涨10M。(message.compressRatio = 1.0 // 设置压缩率),message.compressRatio = 0.2,每发送一张图片内存也要涨5M。

新问题:

即时通讯App在发送图片消息时每次展示一张图片内存涨10M多。

可能原因分析:

1.图片加载方法不对

Cell图片展示

[UIImage imageNamed:]的内存缓存特性:

  • 系统级缓存无法自动释放

  • 特别不适合大图和列表展示场景

  • 会自动缓存图片到系统缓存

  • 适合重复使用的小图标

  • 不适合大图或单次使用的图片

2.内存增长原因:

为了支持 GIF/WebP 等动图格式,showImageView为SDAnimatedImageView,它解码后的帧缓存会增加内存占用。

  • 大图被缓存且无法及时释放

  • 图片解码后的位图数据占用内存

3.Cell 复用机制

快速滑动时可能同时加载多张大图,旧图片未及时释放

优化方案:

通过以下优化措施,图片展示内存问题应该能得到显著改善。核心要点是:

  • 避免使用 imageNamed: 加载大图

  • 合理配置 SDAnimatedImageView

  • 完善 cell 复用机制

  • 使用图片下采样技术

  • 滑动时优化资源使用

1.使用正确的图片加载方式,用 [UIImage imageWithContentsOfFile:filePath]替代[UIImage imageNamed:filePath]

优点:

  • 不会缓存图片

  • 适合大图和单次使用的图片

后台线程解码 + 尺寸适配

// 后台线程处理图片
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{@autoreleasepool {// 1. 从文件加载UIImage *originalImage = [UIImage imageWithContentsOfFile:filePath];// 2. 压缩图片尺寸 (按需)CGSize targetSize = CGSizeMake(800, 800); // 根据需求调整UIGraphicsBeginImageContextWithOptions(targetSize, NO, [UIScreen mainScreen].scale);[originalImage drawInRect:CGRectMake(0, 0, targetSize.width, targetSize.height)];UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();// 3. 主线程更新UIdispatch_async(dispatch_get_main_queue(), ^{self.showImageView.image = scaledImage;});}
});

2.使用 ImageIO 框架高效加载

#import <ImageIO/ImageIO.h>NSURL *imageURL = [NSURL fileURLWithPath:filePath];
NSDictionary *options = @{(id)kCGImageSourceShouldCache: @NO}; // 禁用解码缓存
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)imageURL, NULL);
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)options);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CFRelease(source);self.showImageView.image = image;

3.使用第三方图片加载库

// 使用SDWebImage示例
#import <SDWebImage/SDWebImage.h>[self.showImageView sd_setImageWithURL:[NSURL fileURLWithPath:filePath]placeholderImage:nilcompleted:^(UIImage *image, NSError *error,SDImageCacheType cacheType, NSURL *imageURL) {// 加载完成回调}];

4.优化 SDAnimatedImageView 配置

- (SDAnimatedImageView *)showImageView {if (!_showImageView) {_showImageView = [[SDAnimatedImageView alloc] init];_showImageView.contentMode = UIViewContentModeScaleAspectFill;_showImageView.userInteractionEnabled = YES;// 添加以下优化配置_showImageView.shouldIncrementalLoad = YES; // 渐进式加载_showImageView.maxBufferSize = 1024 * 1024; // 设置合理的缓冲区大小_showImageView.runLoopMode = NSDefaultRunLoopMode; // 滑动时暂停动画}return _showImageView;
}

5.Cell 复用时的内存管理

// 在 cell 的 prepareForReuse 中清理
- (void)prepareForReuse {[super prepareForReuse];// 停止动画并释放资源[self.showImageView stopAnimating];self.showImageView.currentFrame = nil;self.showImageView.animationImages = nil;// 取消未完成的图片加载[self.showImageView sd_cancelCurrentImageLoad];
}

6.图片尺寸优化(针对大图)

// 使用 ImageIO 进行下采样
- (UIImage *)downsampleImageAtPath:(NSString *)path toSize:(CGSize)size {NSURL *url = [NSURL fileURLWithPath:path];NSDictionary *options = @{(id)kCGImageSourceShouldCache: @NO,(id)kCGImageSourceShouldAllowFloat: @YES};CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);CGFloat maxDimension = MAX(size.width, size.height) * [UIScreen mainScreen].scale;NSDictionary *downsampleOptions = @{(id)kCGImageSourceCreateThumbnailFromImageAlways: @YES,(id)kCGImageSourceShouldCacheImmediately: @YES,(id)kCGImageSourceThumbnailMaxPixelSize: @(maxDimension)};CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, (CFDictionaryRef)downsampleOptions);UIImage *image = [UIImage imageWithCGImage:imageRef];if (imageRef) CFRelease(imageRef);if (source) CFRelease(source);return image;
}

7.滑动性能优化

// 在 scrollView 代理中实现以下方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {// 暂停屏幕外 cell 的动画for (UITableViewCell *cell in self.tableView.visibleCells) {if ([cell isKindOfClass:[YourCellClass class]]) {YourCellClass *yourCell = (YourCellClass *)cell;[yourCell.showImageView startAnimating];}}// 暂停非可见 cell 的动画NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];for (NSIndexPath *indexPath in self.loadedIndexPaths) {if (![visiblePaths containsObject:indexPath]) {YourCellClass *cell = (YourCellClass *)[self.tableView cellForRowAtIndexPath:indexPath];[cell.showImageView stopAnimating];}}
}

其他优化建议:

1.内存警告处理

- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// 清除所有图片缓存[[SDImageCache sharedImageCache] clearMemory];
}

2.使用合适的 SDWebImage 选项:

[self.showImageView sd_setImageWithURL:imageURLplaceholderImage:niloptions:SDWebImageAvoidDecodeImage | SDWebImageScaleDownLargeImages |SDWebImageProgressiveLoadcompleted:nil];

3.监控内存使用:

- (void)monitorMemoryUsage {struct task_basic_info info;mach_msg_type_number_t size = sizeof(info);kern_return_t kerr = task_info(mach_task_self(),TASK_BASIC_INFO,(task_info_t)&info,&size);if (kerr == KERN_SUCCESS) {NSLog(@"Memory in use (in MB): %f", info.resident_size / 1024.0 / 1024.0);}
}

4.配置 SDWebImage 全局参数(AppDelegate 中)

// 设置全局缓存策略
SDImageCacheConfig *cacheConfig = [SDImageCacheConfig defaultCacheConfig];
cacheConfig.maxMemoryCost = 100 * 1024 * 1024; // 100MB 内存缓存
cacheConfig.maxMemoryCount = 50; // 最大缓存图片数量
cacheConfig.shouldDecompressImages = NO; // 禁止自动解压
[SDImageCache sharedImageCache].config = cacheConfig;

性能对比

http://www.shuangfujiaoyu.com/news/23530.html

相关文章:

  • 门户网站开发维护合同范本在线培训系统app
  • centos6.6做网站北京网站优化实战
  • 帮别人做app网站门户的兼职seo关键词搜索优化
  • 做网站开发的有哪些公司好重庆百度快照优化
  • 一个公司可以有两个网站吗公司建立网站的步骤
  • 网站优化内容有哪些网络优化器免费
  • 做网站前期构架图如何自己编写网站
  • 做论坛网站的应用账户竞价托管公司
  • 滨海网站建设找哪家好帮别人发广告赚钱平台
  • 个人微信公众号怎么做微网站吗海外aso优化
  • 小米网站制作百度统计数据
  • 网上如何做广告如何优化网站
  • asp.net获取网站虚拟目录品牌营销策划方案怎么做才好
  • 阆中做网站pc端百度
  • 做电影网站用什么格式好谷歌浏览器 安卓下载2023版
  • 做电影网站靠谱吗seo诊断书
  • 自己做购物网站好吗电商网站开发
  • 自己ip做网站重庆网站搜索引擎seo
  • 网站建设费能算作广告费用吗今天的新闻 联播最新消息
  • 新网站推广方法优化服务内容
  • ps做网站logo尺寸关键词优化难度分析
  • 天津 企业网站建设自助建站的优势
  • 做境外旅游的网站网络营销网站有哪些
  • 做网站简约学校网站电脑软件推广平台
  • 网站建费用软文素材库
  • 做微信商城网站哪家好一站式网站建设公司
  • 临安做网站的公司有哪些灰色词快速上排名
  • 网站建设销售客户疑问网络营销的手段包括
  • 推荐做木工的视频网站如何推广好一个产品
  • 源创派网站建设泰州网站优化公司