iOS内存探秘
http://www.cocoachina.com/ios/20170216/18689.html
iOS 内存机制特点
有限的可用内存
iPhone 设备的 RAM 一直非常紧缺,iPhone 一代只有 128MB,直到 iPhone5 时达到了 1GB,并且在 iPhone7 plus 达到了 3GB。StackOverFlow 上提供了部分 iPhone 机型的可用内存数目。
低内存通知
在可用物理内存较少时,iOS 会给各应用发出低内存广播通知,如果此后可用内存仍然低于特定值,则会杀死优先级较低的进程。
没有内存交换机制
桌面操作系统可以在物理内存紧张的时候把暂时不用的物理内存置换到磁盘上,并在需要的时候再次加载到内存中。而 iOS 没有这种机制,原因是移动设备的闪存没有 PC 机那么大的硬盘,而且频繁的读写闪存会降低其寿命。目前 iOS 在内存不足时采用的方案是杀死优先级较低的进程。
使用虚拟内存机制
和大多数桌面操作系统一样,iOS 也使用虚拟内存机制。
虚拟内存
关于虚拟内存的原理和优缺点就不再累述,这里说下 iOS 虚拟内存机制中与众不同的地方。
内存分页
iOS 把虚拟内存每 4KB 划分成一个 Page,并不是所有的 Page 都会映射到物理内存中。每个 Page 有三种状态:
Nonresident
是否 Resident 是一个 Page 状态的重要标识,如果 Page 被映射到内存里了,这个 Page 就是 Resident 状态,否则就是 Nonresident 状态;
Resident and clean
基于 readonly 文件而被加载到内存中的 Page 称为 clean memory,比如:系统 framework、可执行文件、通过 mmap 方式读取的文件 等。这种 Page 由于是加载自不可变的文件,因此可以在物理内存紧张时被 iOS 自动 unload 出去,并且在需要的时候再重新从原来的文件加载到内存中。
Resident and dirty
凡是非 clean 的 Page 都是 dirty 的,它们的共同特点是 Page 在闪存中没有对应的文件,比如通过 alloc 在堆上创建的内存空间,已经解压的图片,database caches 等。dirty memory 不能被操作系统交换出去,只有在进程被杀死的时候才能被回收,因此在系统发生内存告警时,如果进程创建了大量的 dirty memory,那么将很有可能被 kill 掉。
举例说明
Malloc 分配内存
如前问所述,Malloc 的内存都是 Resident dirty 的,但事实上并非如此,比如:
1
|
char *p = valloc(2 * 4096); |
此时会在虚拟内存里申请两份 4096 字节的内存,但由于申请后没有使用,操作系统不会真正为刚申请的内存空间分配对应的物理内存空间,因此此时该内存空间处于 Nonresident 状态。如果对 p[0] 赋值:
1
|
p[0] = 1; |
此时 P[0] 会被加载到物理内存上,由此变成 Resident dirty 状态,同理如果对 p[1] 赋值也一样。
mmap 加载文件
一个文件通过如果下述 mmap 方式加载:
1
|
NSData *data = [NSData dataWithContentsOfMappedFile:file];char *p = (char *)[data bytes]; |
此时文件由于未被使用,因此也仅仅是在虚拟内存中,操作系统并没有将其映射到物理里,因此所属 Page 的状态是 Nonresident。如果调用以下代码:
1
|
printf( "%c" , p[0]); |
此时由于该文件的 p[0] 部分被使用,操作系统就会将 p[0] 部分加载到物理内存中,又因为 p 对应的存储区域是一个 mmap 方式加载的只读文件,因此 p[0] 对应的 Page 就是 Resident clean 的,而 p[1] 往后的部分由于仍然未被使用,Page 的状态不变。
需要做什么
对于开发者来说,要想减少应用因内存告警被系统杀掉,应做到以下几点:
该尽可能减少 dirty 内存的创建
要尽量保证 dirty 内存用完之后及时释放
及时处理系统内存告警通知,释放掉大量占用内存并且可重建的对象
在发生内存告警时,不再持续申请内存,更不能申请较大块的内存
参考文档
WWDC2010 Session 417:Advanced Performance Optimization on iPhone OS, Part 2
WWDC2012 Session 242:iOS App Performance: Memory
iOS内存探秘的更多相关文章
- iOS内存管理
iOS内存管理的方式是引用计数机制.分为MRC(人式引用计数)和ARC(自动引用计数). 为什么要学习内存管理? 内存管理方式是引用计数机制,通过控制对象的引用计数来实现操作对象的功能.一个对象的生命 ...
- 【Bugly干货分享】iOS内存管理:从MRC到ARC实践
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...
- iOS内存管理个人总结
一.变量,本质代表一段可以操作的内存,她使用方式无非就是内存符号化+数据类型 1.保存变量有三个区域: 1>静态存储区 2>stack 3>heap 2.变量又根据声明的位置有两种称 ...
- IOS内存管理学习笔记
内存管理作为iOS中非常重要的部分,每一个iOS开发者都应该深入了解iOS内存管理,最近在学习iOS中整理出了一些知识点,先从MRC开始说起. 1.当一个对象在创建之后它的引用计数器为1,当调用这个对 ...
- iOS内存管理编程指南
iOS 内存管理 目录[-] 一:基本原则 二:成员变量的内存管理 三:容器对象与内存管理 四:稀缺资源的管理 五:AutoRelease 六:其他注意事项 iOS下内存管理的基本思想就是引用计数,通 ...
- iOS内存管理(一)
最近有时间,正好把iOS相关的基础知识好好的梳理了一下,记录一下内存相关方面的知识. 在理解内存管理之前我觉得先对堆区和栈区有一定的了解是非常有必要的. 栈区:就是由编译器自动管理内存分配,释放过程的 ...
- IOS内存nil与release的区别
IOS内存nil与release的区别 分类: IOS内存管理 nil和release的作用: nil就是把一个对象的指针置为空,只是切断了指针与内存中对象的联系:而release才是真正通知 ...
- iOS内存管理 ARC与MRC
想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC ...
- 【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类
背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题.我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题.视图和控制器相关的内存泄露,几乎都不存在了.后来想着一直就那个工 ...
随机推荐
- 51nod1347(简单逻辑)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1347 题意:中文题诶- 思路:稍推理一下就可以发现字符串a是 ...
- 洛谷P3138 [USACO16FEB]负载平衡Load Balancing_Silver
P3138 [USACO16FEB]负载平衡Load Balancing_Silver 题目描述 Farmer John's NN cows are each standing at distinct ...
- 洛谷P1034 矩形覆盖
P1034 矩形覆盖 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4( ...
- IO模式和IO多路复用详解
网络编程里常听到阻塞IO.非阻塞IO.同步IO.异步IO等概念,总听别人装13不如自己下来钻研一下.不过,搞清楚这些概念之前,还得先回顾一些基础的概念. 1 基础知识回顾 注意:咱们下面说的都是Lin ...
- 使用HTTP协议访问网络(Android)
在做项目的过程中需要连接服务器访问数据,还没有接触过Android网络编程方面,参考了<Android第一行代码>,在做的过程中遇到了很多的问题,这里就此记录一下. 先给出访问网络的代码: ...
- Asp.net Core 添加 EF 工具并执行初始迁移错误解决方法(Add-Migration Initial---Build failed.)
1.问题: 首次在ASP.NET Core项目中使用Code First模式的Entity Framework框架,在添加EF工具并做初始化迁移(perform initial migration), ...
- Spring学习(六)整合web开发
https://www.cnblogs.com/Leo_wl/p/4459274.html 1.加载Spring核心配置文件 //1.加载Spring配置文件,根据创建对对象 ApplicationC ...
- Java面向对象_包装类访问修饰符
在java中有一个设计的原则"一切皆对象",java中的基本数据类型就完全不符合这种设计思想,因为八种基本数据类型并不是引用数据类型,所以java中为了解决这样的问题,jdk1.5 ...
- 1.- Netty设计理念-异步和事件驱动
0. 关键点 a). 非阻塞网络调用,异步方法立即返回 b). 选择器(Selector)使得单一线程就可监控很多连接上的事件. <dependency> <groupId>i ...
- (一)Redis简介和安装
1 Redis介绍 1.1 什么是NoSql 为了解决高并发.高可扩展.高可用.大数据存储问题而产生的数据库解决方案,就是NoSql数据库. NoSQL,泛指非关系型的数据库,N ...