使用SDWebImage和YYImage下载高分辨率图,导致内存暴增的解决办法

ios加载图片内存暴涨解决方法 ios加载图片内存暴涨解决方法,第一中UIKit-setImage,第二种苹果官方demo提供的分片比例裁剪方式,第三种CATiledLayer 详见Demo 立即下载

最近,收到朋友求助,说是有个控制器,一进去就crash,而且手机非常的烫,用instrument跑了跑,发现内存暴增几百兆;如图:

1278915-87dba9f8afd74039.png

  图中可以看出,内存暴增的罪魁祸首是YYImage,再进一步定位问题,如图:

1278915-4c27d79315c03ab6.png


  现在已经可以很清楚的知道,具体是哪些代码导致内存飙升的,这个方法“YYCGImageCreateDecodeCopy”,主要是对图像进行解压缩操作;同样的,换成SDWebImage,也出现了相同情况,由于某些原因,之后的分析都将以SDWebImage为例。
  先贴上朋友调用的SDWebImage的代码:

[self sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"defaulImage"] options:SDWebImageProgressiveDownload completed:nil];

instrument分析图:

1278915-f157591f011528ec.png


代码定位:

1278915-2a1700d5dbdedd80.png


  同样的,也是在解压缩的时候,出现内存飙升,但是为什么会这样呢?
  首先我想到“Create”必须得对应一个“Release”,于是我认真的看了每一行代码,无论是YYImage还是SDWebImage,都严格遵守了这一准则,既然都有Release,那么就不是内存泄露了,应该是在这几行代码执行的过程中,产生的内存消耗。可是怎么会消耗这么大呢?一张图片也就几M的大小啊,这个解压缩存在的意义是什么呢?
  我从“H_伟华 博乐家园”的一篇博客中找到了解压缩存在的意义(http://blog.163.com/huang1988519@126/blog/static/737875752013101803137445/)

当完成图片加载或者从本地加载图片时,还会有轻微的卡顿。
因为当显示或者绘制的时候,UIKit 只做了额外的延迟初始化和消耗很高解码。
而下面的代码片段,从后台线程解压缩成合适的格式,从而让系统不必做额外的转换。
然后在主线程上显示

  我又疑惑了,既然是为了优化,为啥会适得其反呢?我百思不得其解,最后在SDWebImage的issues找到了相关的讨论:
https://github.com/rs/SDWebImage/issues/538
其中一个harishkashyap大神是这么回答的:

harishkashyap commented on Dec 23, 2014
Its the memory issue again. decodedImageWithImage takes up huge memory and causes the app to crash. I have added an option to put this off in the library but defaulting to YES so there aren't any breaking changes. If you put off the decodeImageWithImage method in both image cache and image downloader then you shouldn't be seeing the VM: CG Raster data on the top consuming lots of memory

decodeImageWithImage is supposed to decompress images and cache them so the loading on tableviews/collectionviews become better. However, with large set of images being loaded, the experience worsened and the memory of uncompressed images even with thumbnails can consume GBs of memory. Putting this off only improved performance.

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

https://github.com/harishkashyap/SDWebImage/tree/fix-memory-issues

这位大神提到,decodeImageWithImage这个方法用于对图片进行解压缩并且缓存起来,以保证tableviews/collectionviews 交互更加流畅,但是如果是加载高分辨率图片的话,会适得其反,有可能造成上G的内存消耗。该大神建议,对于高分辨率的图片,应该禁止解压缩操作,相关的代码处理为:

[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

虽然这位大神给了肯定的答案,但是为什么会如此呢?
我查阅了apple官方文档对CGBitmapContextCreate函数的注解:



图中红框部分的参数,引起了我的注意:

bitsPerComponent 表示存入内存中的每个像素中的每一个组件所占的位数;
bytesPerRow 表示存入内存中的位图的每一行所占的字节数;

  我猜测,解压缩操作中,每一个像素点都会分配一个空间来存储相关值,那么分辨率越高的图片,就意味着更多数量的像素点,也就意味着需要分配更多的空间!所以对于高分辨率图来说,解压缩操作的确会造成内存飙升,即使是几M的图片,解压缩过程中也是有可能消耗上G的内存!
  既然如此,我决定按照harishkashyap大神的方法,直接让下载高分辨率图的地方,禁止解压缩操作!
  朋友说,高清图涉及到的地方,都全部已经封装起来了,那么就轻松了很多。为了保证封装类不对外界产生影响,我只在调用封装类时,禁用解压缩,调用完毕再恢复原设置即可。这样既能保证高分辨率图不crash,也能保证其他地方,普通图片依旧可以通过解压缩进行优化。
  朋友封装的是一个控制器,所以我决定在控制器loadView方法中禁用解压缩,在delloc方法中恢复原设置:
1、首先在封装的控制器中定义变量用于存储原设置:

static BOOL SDImageCacheOldShouldDecompressImages = YES;static BOOL SDImagedownloderOldShouldDecompressImages = YES;

2、loadView中保存原设置并且禁用解压缩:

SDImageCache *canche = [SDImageCache sharedImageCache];
SDImageCacheOldShouldDecompressImages = canche.shouldDecompressImages;
canche.shouldDecompressImages = NO;

SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];
SDImagedownloderOldShouldDecompressImages = downloder.shouldDecompressImages;
downloder.shouldDecompressImages = NO;

3、dell中恢复原设置:

-(void)dealloc {
    SDImageCache *canche = [SDImageCache sharedImageCache];
    canche.shouldDecompressImages = SDImageCacheOldShouldDecompressImages;

    SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];
    downloder.shouldDecompressImages = SDImagedownloderOldShouldDecompressImages;
}

再次用instrument跑了一下,方法果然有效,内存彻底降下来了,如图:



当然,你也可以设置SDWebImage的其他参数,比如是否缓存到内存以及内存缓存最高限制等,来保证内存安全:

shouldCacheImagesInMemory 是否缓存到内存
maxMemoryCost  内存缓存最高限制

号外:苹果官方给出了一个下载高清大图的demo,内存消耗很低。感兴趣的朋友也可以看看:
https://developer.apple.com/library/ios/samplecode/LargeImageDownsizing/Introduction/Intro.html



文章转自  ocarol的简书
AOSP 8.0.0编译中的ANDROID_DATA缺失问题解决方案 在AOSP编译过程中,环境变量和路径设置的正确性至关重要。遇到相关的错误时,检查并修正环境配置通常是解决问题的关键。希望本文提供的分析和解决方案能帮助你顺利编译AOSP。 阅读详情

相关推荐

Supervisor 安装与使用

一、Supervisor 介绍 Supervisor 是一个用 Python 编写的进程管理工具,它可以用于监控和控制类 UNIX 操作系统上的多个进程。它是一个客户端/服务器系统,其中 Supervisor 的服务器端称为 supervisord,负责启动管理的子进程、响应客户端命令、重启崩溃或退出的子进程、记录子进程的 stdout 和 stderr 输出,以及处理子进程生命周期中的事件。客...

疯子丶pony的博客 3863

解决SDWebimage加载过多过大图片导致内存爆表崩溃的问题

问题: Restore the connection to “xxxx” and run “xx” again, or if “xx” is still running, you can attach to it by selecting Debug > Attach to Process > xx. 原因: collectionView一屏加载显示多个大图,导致内存消耗激增,...

学习笔记 8880

因内存不足原因导致fragment空白解决方案

在androidx之前,一般我们防止Fragment重建是在actvitity的onCreate方法中使用savedInstanceState?.remove(“android:support:fragments”)或者savedInstanceState?但是在androidx中,使用这两行代码不生效,但是看FragmentActivity中的FRAGMENT_TAG还是android:support:fragments,那为什么会不生效呢,后来点进去看发现。

qq_39431405的博客 547

YYWebImage工作原理介绍-----下载单张图片

YYWebImage简介 YYWebImage是由ibireme开发的YYkit其中的一个库,专门处理图像。github传送门:YYWebImage。他的出现是为了替代 SDWebImage、PINRemoteImage、FLAnimatedImage 等开源框架。在YYImage出来之前,我们的图片下载和动态图片展示需要SD和FL两个库去处理。现在YYImage的出现使得统一图像库成为可能。这

努力,可能成功!放弃,注定失败! 6725

RT-2(robotics-transformer2)论文--阅读笔记

谷歌RT-2机器人论文的阅读笔记。

weixin_61255639的博客 1828

基于SVPWM控制策略的二极管钳位型NPC逆变器并网闭环simulink仿真

本文介绍了二极管钳位型三电平SVPWM技术在逆变器中的应用,通过控制IGBT的开关状态,将直流电压转换为三相交流电压,并采用钳位技术降低谐波失真,提高输出质量。文章还描述了基于SVPWM控制策略的二极管钳位型NPC逆变器并网闭环的Simulink仿真模型,该模型实现了并网控制,具有优异的性能,THD小于1%,适用于新手学习。仿真模型参数包括DC 800V、AC 380V、功率100kw,采用三电平NPC拓扑结构和SVPWM闭环控制策略,配备LCL滤波器,生成三电平波形,监测交流侧电压电流、有功功率和无功功率

2510_91195931的博客 466

完美解决SDWebImage加载多个图片内存崩溃的问题

SDWebImage大家肯定都恨熟悉了,国内外太多的App使用其进行图片加载。 但是最近在使用过程中发现,我用SDWebImage加载多个图片,类似微博动态那种,在加载的过程中。我发现当图片分辨率比较大的时候(不是图片大),加载几张图片就崩溃了。 网上说可以每次加载图片清空memcache,但是效果并不好。 [[SDImageCache sharedImageCache]

benyoulai5的专栏 3万+

基于Simulink的BCH码编解码仿真建模示例

BCH码是一类循环码,能够纠正一定数量的随机错误。灵活性:可以根据需要选择不同的码长和纠错能力。高效性:适用于短码长和中等码长的场景,广泛用于卫星通信、存储系统等。实现简单:编码和解码过程可以通过硬件或软件高效实现。在本示例中,我们将使用MATLAB/Simulink中的和模块来完成BCH码的编解码操作,并通过仿真验证其误码率(BER)性能。通过本指南,我们介绍了如何基于Simulink搭建一个BCH码的编解码模型,并进行了仿真以验证其性能。背景介绍:理解BCH码的基本原理及其在通信系统中的应用。

xiaoheshang_123的博客 191

SDWebImage加载多张图片时内存暴增

最近项目中遇到一个问题 在tableview上展示多张图片,在加载的过程中,图片过多时,加载几张图片就崩溃了。内存溢出 为什么会出现这种情况 这个原因其实很明显,SDWebImage产生的图片缓存过多,造成APP内存溢出,崩溃了。 有三个解决办法: 方法一: 然后更改图片的大小,在tableview中展示缩略图,点击查看的时候显示原图。减少由于加载原图而占用过多的内存。...

humiaor的博客 2300

Sigrity SPEED2000 General SI Simulation模式如何进行信号仿真分析操作指导-DDR

本例是几个简单的板载DDR颗粒的结构,本例中使用General SI Simulation模式仿真DDR信号,结构拓扑如下,Addcmd,clk,cke都是T拓扑。Sigrity SPEED2000 General SI Simulation模式可以对信号进行仿真分析,仿真将电源视为理想电源,以下图为例进行说明。DQS的接收端模型设置为DQS_34_ODT60_1333。模式如何进行信号仿真分析操作指导-DDR。附带驱动和接收端的IBIS模型。

weixin_54787054的博客 512

基于STM32的室内环境监测系统设计与实现

摘要 本文设计了一种基于STM32的室内环境监测系统,通过传感器实时采集温湿度、空气质量、烟雾浓度等数据,并利用Wi-Fi模块上传至云服务器。系统采用STM32F103C8T6作为主控芯片,结合DHT11、MQ系列传感器及BMP280气压传感器实现数据采集,通过ESP8266模块实现远程数据传输。用户可通过手机APP实时查看环境参数,并在数据超标时触发报警。实验表明,系统运行稳定,监测精度高,具有低成本、易扩展等特点,为改善室内环境质量提供了有效解决方案。 关键词:STM32;室内环境监测;传感器;Wi-F

3254968421的博客 221

(转)使用SDWebImage和YYImage下载高分辨率图,导致内存暴增的解决办法

http://blog.youkuaiyun.com/guojiezhi/article/details/52033796 转载于:https://www.cnblogs.com/cnman/p/6737785.html

weixin_30432179的博客 208

华为OD机试真题2025双机位A卷 C++ 实现【采购订单】

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

MISAYAONE的博客 674

iOS自问自答:总结内存管理与优化

目录 ARC下如何避免内存泄露?如何检测? 你是如何做内存优化的? __block你知道多少?在什么时候使用? 关于防止APP崩溃你做了哪些努力? 你是如何做线上Bug定位的? 关于经验和技巧还有什么想说的? 1. ARC下如何避免内存泄露?如何检测? 避免: 注意使用block时是否造成循环引用,使用__weak 配合 __strong关键字打...

夜阑微静的备忘录 349

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

目录

Weekly 第一期(2017.03.31) iOS App 签名的原理 - by ll 响应链 - by ff iOS10 系统跳转到系统设置 - by lm 深入思考NSNotification - by ak Weekly 第二期(2017.04.07) 使用SDWebImage和YYImage下载高分辨率图,导致内存暴增的解决办法 - by lm iOS圆角避免离屏渲染...

Philm_iOS的博客 576

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

YYImage实现思路源码分析(图片解压缩原理)

YYKit组件之一---->YYImage 图像处理 移动端图片格式调研 图片处理的小技巧 YYWebImage源码分析 YYModel源码分析 YYText源码分析   核心思路--->图片解码 (二进制数据<-->位图) 雷纯峰的分析 这段是前言,介绍下图片是如何解码的。不想看到的可以直接无视   核心代码: [_decoder frameAtI...

Deft_MKJing的博客 4193

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

YYImage源码剖析与学习

源码剖析学习系列:(不断更新) 1、FBKVOController源码剖析与学习 2、MJRefresh源码剖析与学习 3、YYImage源码剖析与学习 前言: 要看懂YYImage框架,最好先了解热身部分(具体的自行百度),如果懒得看,直接跨过该部分,等到下面部分有疑问,再回过头看这部分的知识,也是可以。 热身部分 移动端图片格式调研 1、Image I/O Image I/O 学习笔记...

weixin_33757911的博客 337

iOS ☞ SDWebimage 内存暴增问题

SDWebImage 底层逻辑,以及使用SDWebImage而引发的内存暴增问题

HumorousGhost 2854

关于使用SDWebImage内存爆涨的问题

这几天在做一个需求,需要在一系列的控制器里下载N张图片。最方便最省事的解决方案当然首选SDWebImage这个框架(相信也很少不去用它的)。把图片地址放进去,返回一个图片,轻松,快捷,令人幸福,直到看到下面这个画面。 屏幕快照 2016-07-14 下午4.56.39.png 什么鬼!内存竟然从20M给我彪到了180+M!而且当我把控制器移除之后,内存竟然也没有丝毫的下降,这在APP上

努力,可能成功!放弃,注定失败! 8508

YYWebImage的基本使用: 与SDWebImage 相比在性能方面有很大的提升,YYWebImage 的图片加载的时候不是直接加载原图,而是通过图片重绘的形式将图片加载上去的,性能消耗很小

YYWebImage 是一个异步图片加载框架 (YYKit 组件之一). 其设计目的是试图替代 SDWebImage、PINRemoteImage、FLAnimatedImage 等开源框架,它支持这些开源框架的大部分功能,同时增加了大量新特性、并且有不小的性能提升。 它底层用 YYCache 实现了内存和磁盘缓存, 用 YYImage 实现了 WebP/APNG/GIF 动图的解码和播放

aoublet的博客 4340
上一篇: iOS手机摄像头测心率
下一篇: python socket.error: [Errno 48] Address already in use
args_
博客等级 码龄11年 13粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值