WWDC - iOS内存性能及原理 笔记

iOS内存的基本原理

内存是如何初始化和被管理的?

  • 在iOS内,指针的地址范围很大, 32位CPU上有 4GB 大小, 64位CPU上有 18EB 大小 (大约有2的60次方), 这么大的指针地址范围会致使我们看来系统内存有这么大,实际上物理内存可能没有这么大,这个大小被称为虚拟内存, 在OS X 中系统使用硬盘来存储内存中不经常使用的数据来作为内存的后备存储, 在内存中存有硬盘数据的指针地址, 需要的事后才写入内存.
  • 然而, 在iOS中没有后备存储, iOS中只读类型的数据已经存在硬盘上, 在需要时写入内存使用, 可读写数据是常驻内存的,不会移除, 一旦可使用内存达到临界值, 系统会发出内存不够用的警告,由应用程序主动释放资源,若释放失败或没有排除警告,会直接被系统终结程序.
  • 虚拟内存

    iOS的物理内存被分割成大小为 4KB 的页, 而且不是所有的页都能被应用访问到. 虚拟内存是在kernel和应用层之间的一层,由于当我们每次需要内存的时候都直接调用kernel去申请内存的过程的代价是很大的, 所以底层会直接与虚拟内存申请空间, 虚拟内存会与kernel通信, 创建 VM Object来匹配物理内存,如图:

    在内存的堆中, 我们应用的数据只占一部分, 其他还有framework创建的对象和缓存, 内存中还有一些静态常量, 线程的堆栈, 图片数据, CALayer的缓存, 数据库的缓存

内存类型: 干净内存和脏内存

干净内存: 从磁盘上拷贝到内存中的空间, 比如, 代码, framework,内存映射文件.

脏内存: 其他的内存空间. 比如 在堆上的初始化数据, 数据库缓存,解压的图片数据等.

大部分应用初始化的数据都是脏内存

举例如下:

- (void)displayWelcomeMessage {
NSString *welcomeMessage = [NSString stringWithUTF8String:“Welcome to WWDC!”];
self.alertView.title = welcomeMessage;
[self.alertView show];
}

welcomeMessage 是脏内存, 因为字符串Welcome to WWDC! 在静态数据区,它倍复制一份到堆上给了welcomeMessage.

- (void)displayWelcomeMessage {
NSString *welcomeMessage = @”Welcome to WWDC!”;
self.alertView.title = welcomeMessage;
[self.alertView show];
}

这次welcomeMessage是干净内存, 因为没有复制一份.

- (void)allocateSomeMemory {
void *buf = malloc(10 * 1024 * 1024);
…
}

虽然malloc是在堆上初始化数据, 但是 buf 没有实际存储数据, 所有buf是干净内存.

- (void)allocateSomeMemory {
void *buf = malloc(10 * 1024 * 1024);
for (unsigned int i = 0; i < sizeof(buf), i++) {
 buf[i] = (char)random();
}
…
}

但是一旦使用了buf后, buf就是脏内存了.

UIImage *wwdcLogo = [UIImage imageNamed:@”WWDC12Logo”];

初始化UIImage,UIImage其实是CGImage的包装, CGImage生成jpeg 和 bitmap, 在内存中会有未压缩的bitmap数据,是脏内存.

当iOS运行在低内存是会发生什么

iOS开始的时候, 干净内存比例很大,当我们运行app的时候, 随着运行的进行, 初始化数据, 产生了脏内存, 进而是脏内存比例增大,干净内存比例减小, 最后产生内存压力, 内存不够用了, 这时候系统会终结掉后台应用, 释放属于应用的脏数据, 腾出内存空间.

内存警告

这是一次挑战

  • 会发生在内存有限的设备上
  • 是最后保护用户体验的机会
  • 保证你的应用能响应内存警告,警告通知是在主线程上触发,避免重复的初始化大数据

这是一次机会

  • 尽可能的释放内存,但是不要影响用户体验
  • 内存警告传递到应用程序有几种方式:
    1. 通知

      UIApplicationDidReceiveMemoryWarningNotification

    2. UIApplication代理方法 -[id <UIApplicationDelegate> -applicationDidReceiveMemoryWarning:]
    3. UIViewController方法

      -[UIViewController didReceiveMemoryWarning]

一定要注意脏内存,因为脏内存是由应用创建,如果不清除,只有应用被终结后才能释放, 使用Profile的VM Tracker去检测内存使用情况, 避免出现大范围经常性波动, 减少内存还可以使用 @autoreleasepool.

找到内存的问题

  • 减少内存的使用: 清楚我们应用的视图层级,只创建必要的视图. 避免循环的导致堆增长,不要忽略那些小的对象.
  • 避免内存增长:
    • 不可访问的,没有任何指针指向
    • 不能被再次使用
  • 被抛弃的内存
    • 仍然有指针引用它, 但是被浪费的
    • 从未被使用过
  • 缓存
    • 被引用了和等待使用
    • 可能永远不会被使用了

如何检测内存问题

内存不应该在重复一个操作中持续增长, 比如: push和pop UIViewcontroller,滑动UITableview, 操作数据库搜索

使用工具和陷阱

使用 Allocations Instrument 来检测内存是否泄露, 遇到内存泄露可以检查是否在块中使用了self对象, 应该换成 __weak 修饰的self这样不增加计数引用.

更多的信息可以查阅官方手册.

Instruments Documentation

Instruments User Guide

Instruments User Reference

地址

官方关于虚拟内存的说明

视频: WWDC2012应用性能:内存

如有不正确,欢迎批评!

时间: 2024-11-09 02:15:23

WWDC - iOS内存性能及原理 笔记的相关文章

WWDC心得与延伸:iOS图形性能

学习与延伸 这篇文章主要是学习完Advanced Graphics and Animations for iOS Apps这个session后的总结和相应细节的延伸和细化.主要内容为图形性能与测试工具这两个章节. 目录: Core Animation Pipeline UIBlurEffectView 图形性能 测试工具 总结 Core Animation Pipeline 第一部分主要讲解了Core Animation的工作流程和渲染过程. CoreAnimation的渲染流程可以用下图来概括

深入理解Java虚拟机(jvm性能调优+内存模型+虚拟机原理)视频教程

14套java精品高级架构课,缓存架构,深入Jvm虚拟机,全文检索Elasticsearch,Dubbo分布式Restful 服务,并发原理编程,SpringBoot,SpringCloud,RocketMQ中间件,Mysql分布式集群,服务架构,运 维架构视频教程 14套精品课程介绍: 1.14套精 品是最新整理的课程,都是当下最火的技术,最火的课程,也是全网课程的精品: 2.14套资 源包含:全套完整高清视频.完整源码.配套文档: 3.知识也 是需要投资的,有投入才会有产出(保证投入产出比是

IOS内存管理学习笔记

内存管理作为iOS中非常重要的部分,每一个iOS开发者都应该深入了解iOS内存管理,最近在学习iOS中整理出了一些知识点,先从MRC开始说起. 1.当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc.retain.new.copy方法之后引用计数器自动在原来的基础上加1(ObjC中调用一个对象的方法就是给这个对象发送一个消息),当调用这个对象的release方法之后它的引用计数器减1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象. [e

iOS - 内存管理之超级大坑内存泄漏QAQ

??前段时间被分配到查内存泄漏这种大坑,不胜惶恐!!!结果还真的跳进去了,爬了好长一段时间都没爬出来QAQ.每天开着Leaks各种捣鼓爱啪啪,然后看到一大波"神奇"的内存泄露信息,头都大了. ??不过这虽然是个大坑,不过趁着这次机会可以把内存管理知识好好实践了一遍.或许现在大多数的新项目都是ARC的了,然而在一些实际的大项目中,会重用很多诺干年前(其实也就几年前)的代码,QAQ,而这些代码会有很多实现采用的是MRC的方式,所以项目中就经常可以见到混合着ARC和MRC这两种不同内存管理模

iOS内存管理和malloc源码解读

0. iOS内存基本原理 在接触iOS开发的时候,我们都知道“引用计数”的概念,也知道ARC和MRR,但其实这仅仅是对堆内存上对象的内存管理.用WWDC某Session里的话说,这其实只是内存管理的冰山一角. 在内存管理方面,其实iOS和其它操作系统总体上来说是大同小异的,大的框架原理基本相似,小的细节有所创新和不同. 和其它操作系统上运行的进程类似,iOS App进程的地址空间也分为代码区.数据区.栈区和堆区等.进程开始时,会把mach-o文件中的各部分,按需加载到内存当中. 而对于一般的iP

iOS 内存陷阱

iphone开发过程中,代码中的内存泄露我们很容易用内存检测工具leaks 检测出来,并一一改之,但有些是因为ios 的缺陷和用法上的错误,leaks 检测工具并不能检测出来,你只会看到大量的内存被使用,最后收到didReceiveMemoryWarning,最终导致程序崩溃.以下是开发过程中遇到的一些问题和网上的一些资料,总结了一下: 一.[UIImage imageNamed:]只适合与UI界面中的贴图的读取,较大的资源文件应该尽量避免使用 用UIImage加载本地图像最常用的是下面三种:

提高iOS App性能的建议和技巧

当我们开发iOS应用时,好的性能对我们的App来说是很重要的.你的用户也希望如此,但是如果你的app表现的反应迟钝或者很慢就会让你得到不好的评论. 然而,由于IOS设备的限制有时很难工作得很正确.我们开发时有很多需要我们记住这些容易忘记的决定对性能的影响. 这是为什么我写这篇文章的原因.这篇文章用备忘录的形式集合了25个技巧和诀窍可以用来提高你的app性能.所以耐心的阅读来给你未来的App一个很不错的提高. Note:在优化代码之前,必须保证有个需要解决的问题!不要陷入"pre-optimizi

IOS内存管理

原文链接:http://blog.csdn.net/weiqubo/article/details/7376189 1.  内总管理原则(引用计数)    IOS的对象都继承于NSObject,   该对象有一个方法:retainCount ,内存引用计数. 引用计数在很多技术都用到: window下的COM组件,多线程的信号量,读写锁,思想都一样.       (一般情况下: 后面会讨论例外情况)    alloc      对象分配后引用计数为1    retain    对象的引用计数+1

Java性能调优笔记

Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多.外部处理系统的性能不足.资源消耗不多但程序的响应速度却仍达不到要求. 资源消耗:CPU.文件IO.网络IO.内存. 外部处理系统的性能不足:所调用的其他系统提供的功能或数据库操作的响应速度不够. 资源消耗不多但程序的响应速度却仍达不到要求:程序代码运行效率不够高.未充分使用资源.程序结构不合理. C