iOS虚拟内存

虚拟内存简介

什么是VM Regions呢?要知道这个首先要了解什么是虚拟内存。当我们向系统申请内存时,系统并不会给你返回物理内存的地址,而是给你一个虚拟内存地址。每个进程都拥有相同大小的虚拟地址空间,对于32位的进程,可以拥有4GB的虚拟内存,64位进程则更多,可达18EB。只有我们开始使用申请到的虚拟内存时,系统才会将虚拟地址映射到物理地址上,从而让程序使用真实的物理内存。

内存分页

系统会对虚拟内存和物理内存进行分页,虚拟内存到物理内存的映射都是以页为最小粒度的。在OSX和早期的iOS系统中,物理和虚拟内存都按照4KB的大小进行分页。iOS近期的系统中,基于A7和A8处理器的系统,物理内存按照4KB分页,虚拟内存按照16KB分页。基于A9处理器的系统,物理和虚拟内存都是以16KB进行分页。系统将内存页分为三种状态。

活跃内存页(active pages)- 这种内存页已经被映射到物理内存中,而且近期被访问过,处于活跃状态。
非活跃内存页(inactive pages)- 这种内存页已经被映射到物理内存中,但是近期没有被访问过。
可用的内存页(free pages)- 没有关联到虚拟内存页的物理内存页集合。
当可用的内存页降低到一定的阀值时,系统就会采取低内存应对措施,在OSX中,系统会将非活跃内存页交换到硬盘上,而在iOS中,则会触发Memory Warning,如果你的App没有处理低内存警告并且还在后台占用太多内存,则有可能被杀掉。

VM Region

为了更好的管理内存页,系统将一组连续的内存页关联到一个VMObject上,VMObject主要包含下面的属性。
Resident pages - 已经被映射到物理内存的虚拟内存页列表
Size - 所有内存页所占区域的大小
Pager - 用来处理内存页在硬盘和物理内存中交换问题
Attributes - 这块内存区域的属性,比如读写的权限控制
Shadow - 用作(copy-on-write)写时拷贝的优化
Copy - 用作(copy-on-write)写时拷贝的优化
我们在Instruments的Anonymous VM里看到的每条记录都是一个VMObject或者也可以称之为VM Region

堆(heap)和 VM Region

Instruments中有一个VM Track模版,可以帮助我们清楚的了解heap和VM Region的关系
运行Profile,选择Allocation模版,进入后再添加VM Track模版


iOS虚拟内存_第1张图片
s1

下面是我自己写的一个测试用的工程,选择Regions Map选项可以看到内存分配的详细信息

s2

我们在VM Track中可以看到,一个VM Region有4种size。
Dirty Size
Swapped Size
Resident Size
Virtual Size
Virtual Size顾名思义,就是虚拟内存大小,将一个VM Region的结束地址减去起始地址就是这个值。Resident Size指的是实际使用物理内存的大小。Swapped Size则是交换到硬盘上的大小,仅OSX可用。Dirty Size根据官方的解释我的理解是如果一个内存页想要被复用,必须将内容写到硬盘上的话,这个内存页就是Dirty的。下面是官方对Dirty Size的解释。secondary storage可以理解为硬盘。
The amount of memory currently being used that must be written to secondary storage before being reused.
所以一般来说app运行过程中在堆上动态分配的内存页都是Dirty的,加载动态库或者文件内存映射产生的内存页则是非Dirty的

点击Address Range列的箭头可以看到更详细的内容,这里进入的是SMALL类型的


iOS虚拟内存_第2张图片
s3

总的来说,堆区会被划分成很多不同的VM Region,不同类型的内存分配根据需求进入不同的VM Region。除了MALLOC_LARGE和MALLOC_SMALL外,还有MALLOC_TINY, MALLOC metadata等等

VM Tracker列属性解析

iOS虚拟内存_第3张图片
s4

% of Res, 当前Type的VM Regions总Resident Size占比
Type,VM Regions的Type,All和Dirty算是统计性质的Type,__TEXT表示代码段的内存映射,__DATA表示数据段的内存映射。MALLOC_TINY,MALLOC_LARGE,CG Image等Type可以从VM Region的Extend Info中读取出来
# Regs,当前Type的VM Region总数
Path,VM Region是从哪个文件映射过来,因为有些类似于__DATA和mapped file的内存块是从文件直接映射过来的。
Resident Size,使用的物理内存量。
Dirty Size,使用中的物理内存块如果不交换到硬盘保存状态就不能复用,那么就是Dirty的内存块,比如你主动malloc出来的内存块,如果不保留其中的状态就把它给别人用,那你肯定就无法恢复这个内存块的信息,所以它是Dirty的。如果是一个映射到内存的文件,就算使用它的内存块,还是可以重新从磁盘载入文件到内存的,所以是非Dirty的,比如最上面图中的mapped file那一行,你可以看到Dirty Size是0。
Swapped Size, 在OSX中,不活跃的内存页可以被交换到硬盘,这是被交换的大小。在iOS中,只有非Dirty的内存页可以被交换,或者说是被卸载。
Virtual Size,VM Regions所占虚拟内存的大小
Res. %,Resident Size在Virtual Size中的占比

参考:

https://www.jianshu.com/p/553f34b03624
https://www.jianshu.com/p/f82e2b378455
https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html

你可能感兴趣的:(iOS虚拟内存)