iOS底层系统:虚拟内存

关于做者

E-moss,程序员,爱好阅读和撸狗,主要从事iOS开发工做,公众号:知本集。  
主要分享和编写技术方面文章,不按期分享读书笔记,亦可访问“知本集”Git地址:https://github.com/knowtheroot/KnowTheRoot_iOS,欢迎提出问题和讨论。
复制代码

Git地址:github.com/knowtheroot…git

1、什么是虚拟内存

1.申请内存

当咱们向系统申请内存时,系统并不会直接返回物理内存的地址,而是返回一个虚拟内存地址。从系统角度来讲,每个进程都有相同大小的虚拟内存空间。
只有当进程开始使用申请到的虚拟内存时,系统才会将虚拟地址映射到物理地址上,从而让程序使用真实的物理内存。程序员

2.内存不够怎么办?

当A进程占用了大部份内存,此时B进程须要内存时发现内存不足,系统则会通知App,让App清理内存,既咱们熟知的Memory Warning。github

3.虚拟内存的缺点

虚拟内存也有一样的缺点:硬盘的容量比内存大,但也只是相对的,速度却很是缓慢,若是和硬盘之间的数据交换过于频繁,处理速度就会降低,表面上看起来就像卡住了同样,这种现象称为抖动(Thrushing)。相信不少人都有过计算机中止响应的经历,而形成死机的主要缘由之一就是抖动。bash

2、内存分页

iOS系统会对虚拟内存和物理内存进行分页,虚拟内存到物理内存的映射都是以页为最小粒度的数据结构

1.什么是分页

1.1 分页的核心

将虚拟内存空间和物理内存空间皆划分为大小相同的页面,如4kb、8kb或16kb等。并以页面做为内存空间的最小单位,一个程序的一个页面能够存放在任意一个物理页面里。ide

1.2 分页解决了什么问题

  • 解决空间浪费碎片化问题:因为将虚拟内存空间和物理内存空间按照某种规定的大小进行分配,这里咱们称之为页(Page),而后按照页进行内存分配,也就克服了外部碎片的问题。
  • 解决程序大小受限问题:将当前须要的页面放在内存里,其余暂时不用的页面放在磁盘上,这样一个程序同时占用内存和磁盘,其增加空间就大大增长了。

1.3 内存分页的状态

系统将内存页分为三个状态:
(1)活跃的内存页(active page):内存页已经被映射到物理内存中,并且近期被访问过,处于活跃状态。
(2)非活跃的内存页(inactive page):内存页已经被映射到物理内存中,可是近期没有被访问过。
(3)可用的内存页(free page):没有关联到虚拟内存页的物理内存页集合。函数

当可用的内存页下降到必定的阀值时,系统就会采起低内存应对措施,在OSX中,系统会将非活跃内存页交换到硬盘上,而在iOS中,则会触发Memory Warning,若是你的App没有处理低内存警告而且还在后台占用太多内存,则有可能被杀掉。优化

1.4 页表

页表的功能是提供虚拟页面到物理页面的映射
页表的记录条数与虚拟页面数相同。此外,内存管理单元依赖于页表来进行一切与页面有关的管理活动,这些活动包括判断某一页面号是否在内存里,页面是否受到保护,页面是否非法空间等等。
因为页表的特殊地位,决定了它是由硬件直接提供支持,即页表是一个硬件数据结构spa

3、VMObject

为了更好的管理内存页,系统将一组连续的内存页关联到一个VMObject上。
VMObject主要包含如下属性:指针

  • Resident pages - 已经被映射到物理内存的虚拟内存页列表
  • Size - 全部内存页所占区域的大小
  • Pager - 用来处理内存页在硬盘和物理内存中交换问题
  • Attributes - 这块内存区域的属性,好比读写的权限控制
  • Shadow - 用做(copy-on-write)写时拷贝的优化
  • Copy - 用做(copy-on-write)写时拷贝的优化

4、虚拟内存和堆(heap)

堆区会被划分红不少不一样的VM Region,不一样类型的内存分配根据需求进入不一样的VM Region。

5、malloc和calloc

OC中,除了使用NSObject的alloc分配内存外,还可使用c的函数malloc进行内存分配。malloc的内存分配固然也是先分配虚拟内存,而后使用的时候再映射到物理内存,不过malloc有一个缺陷,必须配合memset将内存区中全部的值设置为0。这样就致使了一个问题,malloc出一块内存区域时,系统并无分配物理内存。然而,调用memset后,系统将会把malloc出的全部虚拟内存关联到物理内存上,由于你访问了全部内存区域。

为了解决这个问题,苹果官方推荐使用calloc代替malloc,calloc返回的内存区域会自动清零,并且只有使用时才会关联到物理内存并清零。

主要区别

calloc和malloc 主要的区别在于前者在返回内存的指针以前将它初始化为0,另外它们请求数量的方式不一样。calloc的参数包括所需元素的数量和每一个元素的字节,根据这些值能够计算出总共须要分配的内存空间(num_elements*element_size)个字节。

相关文章
相关标签/搜索