物理内存
物理内存指的是内存条上的内存,早期一个进程的数据是全部加载在物理内存上,CPU
直接通过物理内存地址来访问进程数据。这种方式会产生以下几个问题:
-
内存不够用
:启动的应用过多,全部加载会导致内存条的空间不够用。 -
内存占用浪费
:当应用越来越大的时候,用户可能只用到部分功能,此时如果全部加载到内存,会导致内存占用浪费。 -
内存数据的安全问题
:通过访问物理地址,可以直接修改物理内存上的数据。
为了解决物理内存的这几个问题,CPU
访问进程数据就不能直接通过物理内存地址,而是通过虚拟内存来间接访问。
虚拟内存
虚拟内存是处于进程和物理内存之间的一个中间层,由系统生成,内部作分页管理,结构如下图所示:
虚拟内存的结构.png一个虚拟内存对应一个进程,大小为4GB
,虚拟内存里会分为很多页(page
),每页的大小在iOS中为16kb
,其他系统中为4kb
。Page
里的每一格对应进程中的某一项数据,会记录该数据的虚拟内存地址和物理内存地址,因此虚拟内存本质上是一张关联进程各项数据的虚拟内存地址和物理内存地址的映射表。
采用虚拟内存后,CPU
访问进程数据的情况如下:
- 进程启动后,系统会为进程建立一个对应的虚拟内存,里面记录了进程每项数据的虚拟内存地址,此时进程还未加载到物理内存中,所以
page
记录的各项数据的物理内存地址为0x00000...。 - 当进程的某部分活跃后,
CPU
根据这部分数据的虚拟内存地址找到其对应的物理内存地址,再通过物理地址访问到物理内存上的数据。 - 如果在
page
上没有找到对应的物理地址时,说明此page
上所关联的进程数据没被加载到物理内存中,此时会触发缺页异常(Page Fault)
,中断当前进程,先将当前页所对应的进程数据加载到物理内存中,然后page
会记录每项数据的物理地址,CPU
再通过物理地址来访问内存上的数据。
因此,相比直接访问物理内存,虚拟内存的优势如下:
-
内存使用更高效
:进程的数据经过分页管理后,只将活跃的page
所关联的数据加载在物理内存中,当物理内存都被占用的时候,此时会覆盖掉不活跃的内存,加载当前活跃的page
数据,这样就能提高对内存的使用效率。 -
内存数据更安全
:每次启动进程,系统都会重新建立对应的虚拟内存,并为虚拟内存分配一个ASLR随机值(Address Space Layout Randomization)
,数据的虚拟地址即为:ASLR随机值+偏移值
,这样数据的虚拟地址每次都会变,并且CPU
是通过虚拟内存来间接访问物理内存的,在这个过程中物理内存地址没有暴露出来,所以就能保证内存数据的安全性。
网友评论