2015-12-21 10:13:14 wangyang6275 阅读数 5167

SDWebImage这里不用多讲,都用过!!!

但是最近在使用过程中发现,在UITableView中不断加载更多的内容,使用SDWebImage会造成内存占用越来越大,稍微找了下问题原因,发现不少开发者都遇到过这个问题,中文的资料没有搜到该问题的解决办法,为了方便国内其他开发者遇到类似问题不浪费时间,这篇blog把解决方法记录如下:

首先检查了SDWebImage代码中对于memory warning的处理:

- (void)clearMemory {
    [self.memCache removeAllObjects];
}

其中self.memCache是NSCache类型的,可以看到SDWebImage本身对内存警告执行了操作,但是并没有什么X用。

用Instruments的allocations分析了一下内存使用情况:技术分享

 

可以看到内存基本都在decodedImageWithImage:这个方法里被占用了

解决方法如下:

添加#import "SDImageCache.h"头文件

在使用SDWebImage加载较多图片造成内存警告时,定期调用

我这边是在上拉刷新的方法里面加入

 [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];

即可解决。


2017-08-28 09:36:48 u010670946 阅读数 182

内存泄露的相关概念:

如果程序运行时一直分配内存而不及时释放无用的内存,程序占用的内存越来越大,直到把系统分配给该APP的内存消耗殚尽,程序因无内存可用导致崩溃,这样的情况我们称之为内存泄漏。

内存泄露可能引发的问题:

1)内存消耗殆尽的时候,程序会因没有内存被杀死,即crash。

2)当内存快要用完的时候,会非常的卡顿。

3)如果是ViewController没有释放掉,引起的内存泄露,还会引起其他很多问题,尤其是和通知相关的。没有被释放掉的ViewController还能接收通知,还会执行相关的动作,所以会引起各种各样的异常情况的发生。(这一点尤为重要,项目中重点关注)

常见的检测监测方法:

1.Analyze静态分析:通过静态分析我们可以最初步的了解到代码的一些不规范的地方和一些代码逻辑上的错误;

2.Leaks,Xcode自带工具。

3.MLeaksFinder,来自微信阅读团队的监测工具,比较精准。有友好的弹框提示,可以定位到相关的类和发生内存泄露的步骤。

常见循环引用:

1.NSTimer:创建定时器时,当前控制器引用而定时器了(为什么因引用定时器?后续要用到这个定时器对象),在给定时器添加任务时,定时器保留了self(当前控制器).这里就出现了循环引用.解决方法:控制器不再引用定时器(不太可能) ,定时器不再保留当前控制器(较为科学,直接停止掉即可)

2.GCD计时器,使用GCD的定时器,要注意使用weakself。

3.VC的内存泄露。解决方法:想要知道ViewController有没有被释放,一个方法就是可以通过看ViewController有没有执行dealloc方法。

4.block内存泄露。解决方法:打断引用循环关系。

5.delegate内存泄露。weak弱引用即可。

6.NSNotification内存泄露:weak弱引用即可。

具体内存问题和解决方案可以看我的github上面的Demo。附上Demo地址,欢迎提出宝贵意见。

demo的github地址:点击打开链接

2019-01-24 10:19:19 a_horse 阅读数 62

一,内存泄露和内存溢出

  • 内存泄漏(memory leak):是指申请的内存空间使用完毕之后未回收。
    • 一次内存泄露危害可以忽略,但若一直泄漏,无论有多少内存,迟早都会被占用光,最终导致程序crash。(因此,开发中我们要尽量避免内存泄漏的出现)
    • 供应方(操作系统)能提供给需求方(App)的内存越来越少。
  • 内存溢出(out of memory):是指程序在申请内存时,没有足够的内存空间供其使用。
    • 通俗理解就是内存不够用了,通常在运行大型应用或游戏时,应用或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。最终导致机器重启或者程序crash。
    • 需求方(App)需要的内存过大,超过供应方(操作系统)负载。

 

二,内存泄露的危害

  • 从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到

 

三,内存泄露的检查方法

  1. MLeaksFinder框架检查内存泄露,弹框显示
  2. 点击调试窗口的Debug Memory Graph,查看引用路径
  3. 静态检查:product -》analyse
  4. 动态检查:product-》profile
  5. 开启僵尸对象检查:如果出现EXC_BAD_ACCESS,启用NSZombieEnabled(edit Scheme -》Diagnostises -》勾选Zombi Object)
  6.  

四,常见内存泄露的原因及解决办法

  1. block的引用
    1. 修饰self:block外部弱化__weak type(self) weakSelf = self,block外部强化__strong typeof(weakSelf) strongSelf = weakSelf;
    2. 修饰变量:没有_ _block修饰是传值,作为常数使用;有修饰是传地址,作为变量使用,可以改变
  2. delegate被强引用,应该改成weak修饰
  3. 控件被strong修饰,应该改成weak修饰
  4. NSTimer未销毁,self作为target;应该改成weakSelf
  5. [UIImage imageNamed:@”“]引用大的图片文件;应该改成改成imageWithContentsOfFile
  6. 大循环未来的及释放,需要自己建autoReleasePool释放池
  7. 通知和KVO未移除
  8. CoreFoundation对象(C对象) : 只要函数中包含了create\new\copy\retain等关键字, 那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数
  9. NSUrlSession产生的内存泄露:delegate为retain,session使用完后置空
  10. UIWebView产生的内存泄露:shouldStartLoadWithRequest代理方法中,有可能URL有重定向,需要判断request的url是否为空,再往下执行NSURLSession的dataTaskWithRequest方法,进行文件的下载

 

 

2011-07-30 22:00:31 mgtts 阅读数 13

iPhone App 现在进入到了iOS4时代,内存问题越来越重要了,以前的iOS都是单任务的,内存还算够用,现在iOS4推出了多任务系统,越来越多的程序占了内存以后,在后台又不释放,使用者也往往会忘记在后台杀掉其他程序的进程,导致现在的程序经常会遇到内存不够用的情况,真不知道这个多任务系统是好是坏丫。
总之,作为一个程序员,有bug就得处理,没办法。。。
接收到内存不够警告很有必要,使用
- (void)didReceiveMemoryWarning {
         [super didReceiveMemoryWarning];
         //TO DO:
}
如果内存不够用,这个方法就能触发了。这时候,建议你释放一些必不要的数据以便腾出足够的内存。

好吧,我承认前面都是废话,下面写点有用的, 关于内存警告级别的解释:

There are 4 levels of warnings (0 to 3). These are set from the kernel memory watcher, and can be obtained by the not-so-public function OSMemoryNotificationCurrentLevel().
typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;
How the levels are triggered is not documented. SpringBoard is configured to do the following in each memory level:
    1.    Warning (not-normal) — Relaunch, or delay auto relaunch of nonessential background apps e.g. Mail.
    2.    Urgent — Quit all background apps, e.g. Safari and iPod.
    3.    Critical and beyond — The kernel will take over, probably killing SpringBoard or even reboot.
Killing the active app (jetsam) is not handled by SpringBoard, but launchd.

根据我的理解,2级以前的警告都可以无视,2级的警告老实说,有点危险,但是我个人的体会是,其实也可以凑合了^_^
因为你如果使用了照相机的话,2级警告其实比较常见

2017-04-14 11:55:46 u014540814 阅读数 4222

昨天ios的硕士实习小伙伴,,,咳咳。在疑惑这个问题,于是就各种找资料。最后只找到两个权威的链接,根据这两个权威的链接,整理如下:

ios的app包含所有版本。

在ios9之前,应用程序的所有版本我们都进行了下载和安装。这意味着不管你的手机需要app的什么图片和资源,所有屏幕尺寸的图片和资源都会被下载。
想想那是多少:

  • Non retina 3.5”
  • Retina 3.5”
  • Retina 4”, 4.7”, 5.5”
  • Non retina iPad full size and Mini
  • Retina full size, Mini and Pro
    这些版本的图片与资源加起来不少哇。而且plus还包括64位和32位的。

Android可扩展布局与图片

另一方面,Android利用可扩展的布局,资源的布局可以扩展到任何大小,因此只需要一个副本。只有图标文件会有很多副本,但是最后也不过5次而已(我们现在基本都是2次罢了,xhdpi和xxhdpi)。

ps:在iOS 9中,苹果推出了App Thinning,这意味着App Store只会下载您的设备所需的资源。

ios与Android的区别

iPhone(.XIB)的UI定义文件比Android中使用的XML文件大得多。
与Android相比,代码加密在IOS中占用更大的空间。

其他可能的原因

另外也有人猜测,Android的应用程序可以运行在虚拟机中,而ios更接近于硬件,导致应用程序在编译的时候,多出了好多和底层交接的代码。当然这个猜测只是猜测而已,并不权威。

可能(不确定)IOS包括应用程序包中的引用库。
在android中,您可以将图像保存在3个独立的文件夹中,以进行不同的配置(ldpi,hdpi,mdpi)。
可能是android在安装过程中选择apt文件,而不包含所有文件。

开发平台的不同,Android很多的开发平台都能创建出一个apk文件,在我们手机中执行的时候程序运行在虚拟机上,而ios不同的开发平台打包的时候还要考虑到所打的包必须能够被x-code编译,因此打包又多了好多文件。(这个理由感觉有点扯淡了)

英语六级建议直接观看:
https://www.quora.com/Why-are-Android-apps-and-games-so-much-smaller-than-iOS-apps-In-size
https://www.quora.com/Why-is-the-file-size-of-an-iOS-app-much-more-than-that-of-an-Android-app-with-almost-the-same-features#

iOS图片缓存

阅读数 3

没有更多推荐了,返回首页