IOS 内存警告 Memory warning level

简介: 内存警告   我们都知道在移动设备上很多资源都是比较紧缺的,尤其时内存,通常都比较小,iPhone4也才只有512MB。而且IOS4.0以后还支持了多任务,这个问题就更加突出了。因此我们在平时设计程序的时候要注意管理好内存,减少不必要的开销,谨防泄露。

内存警告

  我们都知道在移动设备上很多资源都是比较紧缺的,尤其时内存,通常都比较小,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方法,这个时候我们一定要种,释放不必要的资源。

  ~~~~~~~~~~~~~~~~~~~~~~3月9号更新~~~~~~~~~~~~~~~~~~~~~~

  今天回家写了个小例子测试内存泄漏,思路如下:在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、Android、前端开发,有意私聊,博主请你喝️
如果觉得本文帮到了你,记得点赞哦,当然也可以请博主喝一杯豆浆
o_IMG_2722.PNG o_qq.PNG
微信二维码 QQ二维码
目录
相关文章
|
8天前
|
存储 网络协议 大数据
一文读懂RDMA: Remote Direct Memory Access(远程直接内存访问)
该文档详细介绍了RDMA(远程直接内存访问)技术的基本原理、主要特点及其编程接口。RDMA通过硬件直接在应用程序间搬移数据,绕过操作系统协议栈,显著提升网络通信效率,尤其适用于高性能计算和大数据处理等场景。文档还提供了RDMA编程接口的概述及示例代码,帮助开发者更好地理解和应用这一技术。
|
1月前
|
设计模式 uml
在电脑主机(MainFrame)中只需要按下主机的开机按钮(on()),即可调用其它硬件设备和软件的启动方法,如内存(Memory)的自检(check())、CPU的运行(run())、硬盘(Hard
该博客文章通过一个电脑主机启动的示例代码,展示了外观模式(Facade Pattern)的设计模式,其中主机(MainFrame)类通过调用内部硬件组件(如内存、CPU、硬盘)和操作系统的启动方法来实现开机流程,同时讨论了外观模式的优缺点。
|
1月前
|
Swift iOS开发
iOS开发-属性的内存管理
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),不维持对象生命期,可用于解除循环引用;`assign`(赋值),适用于基本数据类型及非指针对象属性;`copy`,复制对象而非引用,确保对象不变性。iOS采用引用计数管理内存,ARC(自动引用计数)自动处理引用增减,简化开发。为避免循环引用,可利用弱引用或Swift中的`[weak self]`。最佳实践包括:选择恰当的内存管理策略、减少不必要的强引用、及时释放不再使用的对象、注意block内存管理,并使用Xcode工具进行内存分析。
|
1月前
|
存储 缓存 监控
托管内存(Managed Memory)
托管内存(Managed Memory)
|
2月前
|
监控 安全 Java
JVM内存问题之排查Direct Memory泄漏有哪些常用方法
JVM内存问题之排查Direct Memory泄漏有哪些常用方法
|
2月前
|
Arthas 监控 Java
JVM内存问题之使用gperftools分析JNI Memory泄漏的具体步骤是什么
JVM内存问题之使用gperftools分析JNI Memory泄漏的具体步骤是什么
|
2月前
|
Java
Java面试题:Java内存模型与并发编程知识点,解释Java中“happens-before”的关系,分析Java中的内存一致性效应(Memory Consistency Effects)及其重要性
Java面试题:Java内存模型与并发编程知识点,解释Java中“happens-before”的关系,分析Java中的内存一致性效应(Memory Consistency Effects)及其重要性
19 0
|
2月前
|
监控 Linux
Linux脚本之监控系统内存使用情况并给予警告
Linux脚本之监控系统内存使用情况并给予警告
|
7天前
|
IDE 开发工具 Android开发
安卓与iOS开发对比:平台选择对项目成功的影响
【9月更文挑战第10天】在移动应用开发的世界中,选择正确的平台是至关重要的。本文将深入探讨安卓和iOS这两大主要移动操作系统的开发环境,通过比较它们的市场份额、开发工具、编程语言和用户群体等方面,为开发者提供一个清晰的指南。我们将分析这两个平台的优势和劣势,并讨论如何根据项目需求和目标受众来做出最佳选择。无论你是初学者还是有经验的开发者,这篇文章都将帮助你更好地理解每个平台的特性,并指导你做出明智的决策。
|
5天前
|
API Android开发 iOS开发
安卓与iOS开发中的线程管理对比
【9月更文挑战第12天】在移动应用的世界中,安卓和iOS平台各自拥有庞大的用户群体。开发者们在这两个平台上构建应用时,线程管理是他们必须面对的关键挑战之一。本文将深入探讨两大平台在线程管理方面的异同,通过直观的代码示例,揭示它们各自的设计理念和实现方式,帮助读者更好地理解如何在安卓与iOS开发中高效地处理多线程任务。