iOS内存警告的等级
来源:互联网 发布:80端口不通怎么办 编辑:程序博客网 时间:2024/05/29 12:18
转载地址:http://blog.csdn.net/likendsl/article/details/8199477
我们都知道在移动设备上很多资源都是比较紧缺的,尤其时内存,通常都比较小,iPhone4也才只有512MB。而且IOS4.0以后还支持了多任务,这个问题就更加突出了。因此我们在平时设计程序的时候要注意管理好内存,减少不必要的开销,谨防泄露。
由于写的一个小项目存在严重的内存泄漏,程序经常运行时间不长就退出了,调试时候发现运行过程中接受到系统的Memry warning level 1几次以后,紧接着收到一个Memory warning level 2,然后程序退出。通常使用xcode4自带的工具,跟踪发现由于一个图像资源忘记release导致。问题解决了,但我没有打算就此带过。接着上网查找了有关Memory warning Level的资料,后来在stackoverflow上面找到一些有用的数据,这是KennyTM写的,跟大家分享一下:
系统有四种内存警告,定义如下:
typedef enum { OSMemoryNotificationLevelAny = -1, OSMemoryNotificationLevelNormal = 0, OSMemoryNotificationLevelWarning = 1, OSMemoryNotificationLevelUrgent = 2, OSMemoryNotificationLevelCritical = 3 } OSMemoryNotificationLevel;
但是这几种警告之间是怎么变化的,到达什么阈值时会从一个level跳到另外一个level,文章中没有提及。
通常我们在程序中接收到最多的就是Memory warning level 1,这个时候就证明系统内存紧张了,我们的程序必须做出相应,释放不必要的内存。通常如果我们处理得当的话,内存警告就会到此停止,恢复正常状态。如果我们在接收到memory warning level 1以后坐视不理的话,系统可能还会再尝试通知几次level 1,如果还是不去处理的话,系统将会发出更高一级的内存警告 level 2,通常的结果就是我们的App被强制退出,系统收回内存。当然系统在发出level 2的警告时,也会取尝试做一些清理内存的事,例如关闭不必要的后台程序等。很显然我们不该寄希望于系统自己清理,这就好比你的胳膊被划破了,身体肯定会有自修复功能,但是如果伤口比较大的话,肯定还是需要人工处理一下的。
到目前位置我还没有见过level 3的警告,根据stack over flow上面讲的“当发生level 3警告时,系统内核将会接管,很有可能关掉IOS的主界面进程(SpringBorad),甚至会重启”,照这个意思来说我们程序里面接收不到,也实属正常,系统自己的东西都被干掉了,我们肯定早被kill了。
KennyTM写的原文地址: http://stackoverflow.com/questions/2915247/iphone-os-memory-warnings-what-do-the-different-levels-mean
如果打开上面的连接,可以看到定义OSMemoryNotificationLevel的源文件,你可能会注意到里面有一个函数OSMemoryNotificationCurrentLevel(),可以用来获取当前内存告警level,不过需要加头文件#import<libkern/OSMemoryNotification.h>
,网上有个查看当前内存数据的开源代码MemWatcher,大家可以看看,说实话我没有看懂。
说了这么多,希望能帮大家弄清楚内存警告是怎么回事儿,通常我们程序是不会碰到内存警告,平时写代码注意在所有alloc,retain,copy的地方,对应的写上release,或者直接创建autorelease对象(个人不推荐这么做),发布前养成检查内存泄露的好习惯。
顺便提一下如果运行过程中遇到内存警告的话,程序通常情况下都先调用AppDelegate中的applicationDidReceiveMemoryWarning, 然后程序会通知各ViewController,调用其didRecieveMemoryWarning方法,这个时候我们一定要种,释放不必要的资源。
今天回家写了个小例子测试内存泄漏,思路如下:在UIViewController的viewDidload中,向self.view添加一个自定义的专门泄漏的UIView(在初始化函数中开启一个线程不停的加载图片)。在我的iPhone4下运行程序后大概不到一分钟以后出现level 1 警告,然后过10秒左右报出level 2警告,再过5秒左右程序被退出。截图如下:
这也证明前面说过的level 3的警告通常我们是接收不到的这个推断。
SvMemoryWarningViewController.m//// SvMemoryWarningViewController.m// SvMemoryWarning//// Created by maple on 3/9/12.// Copyright (c) 2012 SmileEvday. All rights reserved.//#import "SvMemoryWarningViewController.h"#import <libkern/OSMemoryNotification.h>#import "SvLeakMemoryView.h"@interface SvMemoryWarningViewController ()@end@implementation SvMemoryWarningViewController- (void)viewDidLoad{ [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. SvLeakMemoryView *view = [[SvLeakMemoryView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; [self.view addSubview:view]; [view release];}- (void)viewDidUnload{ [super viewDidUnload]; // Release any retained subviews of the main view.}- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ return interfaceOrientation == UIInterfaceOrientationPortrait;}- (void)didReceiveMemoryWarning{ NSLog(@"Recieve memory warning"); NSLog(@"~~~~~~~~~~~~~~level~~~~~~~~~~~~~~~ %d", (int)OSMemoryNotificationCurrentLevel());}@end
SvLeakMemoryView.m#import "SvLeakMemoryView.h"#import <QuartzCore/QuartzCore.h>@implementation SvLeakMemoryView- (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { // Initialization code UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Car" ofType:@"jpg"]; imageView.image = [[UIImage alloc] initWithContentsOfFile:filePath]; imageView.layer.contentsGravity = kCAGravityResizeAspect; [self addSubview:imageView]; NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@"treeHighResolution" ofType:@"jpg"]; dispatch_queue_t loadImageQueue = dispatch_queue_create("load image", NULL); __block UIImageView *testIV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; dispatch_async(loadImageQueue, ^{ while (TRUE) { UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath2]; testIV.image = image; } }); } return self;}/*// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect{ // Drawing code}*/@end
- iOS内存警告的等级
- iOS内存警告的等级
- iOS内存警告的等级
- iOS避免内存警告的一些建议
- iOS避免内存警告的一些建议
- iOS相机内存警告的解决办法
- iOS 加载图片时的内存警告
- iOS 收到内存警告的处理过程
- iOS避免内存警告的一些建议
- iOS内存警告
- iOS内存警告
- iOS内存警告
- iOS内存警告
- IOS内存警告I
- IOS内存警告II
- 关于ios内存警告
- iOS内存警告didReceiveMemoryWarning
- iOS内存警告处理
- PHP学习笔记
- 几种设计模式
- Android SDK更新以及ADT更新出现问题的解决办法
- 最全面的I/O优化介绍 从文件系统到磁盘管理
- 常用正则表达式
- iOS内存警告的等级
- Android View 仿iOS SwitchButton和各种效果集合
- activity启动卡顿问题
- Linux chmod命令修改文件与文件夹权限命令代码
- 字典树模板题&hdu1251
- 140.Examine the structure of the PRODUCTS table:
- [LeetCode]53. Maximum Subarray
- 蓝牙开发简单应用
- 经典排序算法(1) - 冒泡排序Bubble Sort