美文网首页
iOS 内存管理(一)

iOS 内存管理(一)

作者: 明若晴空 | 来源:发表于2021-12-28 17:47 被阅读0次

    iOS 内存管理(一)

    一个APP使用了多少内存。这个内存是一个非常模糊的概念,因为内存一般是由几种不同部分组成的。这里我们就首先了解一下,内存一般指的是什么,都有哪些类型。

    内存类型

    虚拟内存和物理内存

    一般系统APP的内存,都包含这样两个部分,一个是虚拟内存,一个物理内存。

    物理内存

    设备内部的物理内存条上的内存空间。iPhone 7和8之前的手机只有1/2G 内存,iPhone 8p-iPhone12手机一般是3、4、最近新出的iPhone13 达到6GB的内存。
    如果系统要访问地址不在物理内存中时,此时发生缺页中断。需要把对应的虚拟内存映射到物理内存中再使用。
    一般一个APP最多物理内存的使用率到总内存的60-70%时,就会发生OOM。

    虚拟内存

    是一种计算机系统的内存管理技术。虚拟内存为每个进程提供了一个独立的、私有的、连续的逻辑地址空间。
    32位设备,这个地址范围是4GB,对于64位设备来说,是16EB。对于现有的苹果手机来说,基本都是64位。
    通过虚拟内存,我们可以建立起逻辑地址到物理地址的映射,。

    虚拟内存到物理内存的映射

    每一个进程的虚拟内存都有一个逻辑地址空间,当访问的page在物理内存中,就直接执行,如果不在物理内存时,就会从虚拟内存中把对应的page调入到物理内存中。如果此时物理内存满了,不能再调入新的page了,那么就把暂时不需要的page调出到物理内存,腾出足够的内存空间,再将要访问的page置换调入到内存中,让程序得以继续执行。如果暂时腾不出需要的空间,就会发生OOM
    虚拟内存的这个调入/出和置换的功能,使得物理内存得以扩充。

    页式存储

    分页存储管理是将一个进程的这个逻辑地址空间,也就是虚拟内存地址空间,分成多个大小相等的片,并且给各页进行编号,如第0页、第1页。。。
    页面的大小一般是2的幂。如位移量是几位,页面大小就是2的几次幂
    分页的地址结构就是

    页号 位移量

    页面大小合理,可以提高内存的使用效率。

    相应的,物理内存空间也会分成和页面大小一致的若干个存储块,并且依次编号。为了区别期间,我们这里把虚拟内存空间的存储单元称为页及其页号。物理内存中存储单元称为块和块号。

    页表

    要实现逻辑地址空间到物理内存的映射,需要配置一张页表,其结构如下:

    页号 存取状态 块号

    段式存储

    页是信息的物理单位
    段是信息的逻辑单位
    为了满足用户(程序员)在编程和使用上的要求,引入了段式存储。优点:

    • 方便对共享和保护特定段的信息
    • 可以比较方便的动态增长某个段,比如数据段的增长
    • 可以动态链接某个段,比如在程序运行过程中需要调用某个段时,再将该段调入内存进行链接。
      每个段都有自己的编号,并且可以起个段名字。因为每个段的长度是由其相应的逻辑信息组的长度决定的,所以每个段的段长是不同的。
      段的地址结构,如下
    段号 段内地址
    段表

    要实现逻辑段到物理内存的映射,需要配置一张段表寄存器和段表,其中,段表寄存器结构如下:

    段表起始地址 段表长度

    段表结构如下:

    段号 存取状态 段长 段基址

    分页和分段二者都是基于离散分配的内存分配方式,也就是说直接将内存可以分配到许多不相邻的空间分区中。离散分配的基本单位是页的话,就是分页存储方式;离散分配的单位是段的话,就是分段存储方式。

    段页式存储

    分段分页各有优缺点,分页可以提高内存利用率,减少内存浪费。而分段可以更好满足我们用户的需要。结合这两者,各取所长,结合而成的一种新的存储管理方式系统,就是段页式存储系统,既可以实现分段共享,便于信息保护,动态链接,也可以减少内存碎片浪费的问题。

    原理

    先将程序分成多个段,比如数据段、栈段、堆段,每个段都有自己的编号,并且可以起个段名字。每个段都从0开始给地址编号,并且是一段连续的地址空间。段内又分成多个页,每个页面的大小为16KB。因此在段页式存储系统中,地址结构是由段号、段内页号、以及页内地址构成的。如下图:


    未命名文件 4.png
    未命名文件 5.png

    地址变换过程

    在段页式系统中,为了便于实现虚拟内存地址到物理内存地址的变换,需要配置:

    • 段表寄存器,其中存放的是段表的起始地址和段表长度TL。
    • 段表:
    • 页表,这个页表记录了逻辑地址空间中的所有的页(0~n),在内存中对应的物理块号。实现了页号到物理块号的地址映射。

    进行地址变换的时候,

    1. 首先利用段号S和这个段表长度进行比较。如果S<TL,表示未越界,那么就用这个段表的起始地址和段号,求出该段所对应的段在段表中的位置,也就是这个段中的页表的起始地址;若越界,则程序中断。
    2. 然后利用逻辑地址中的段内页号P查找对应页的页表项位置;
    3. 然后再用该页所在的物理块号b和页内地址来构成物理地址;

    具体过程如下图:


    未命名文件 8.png

    在段页式系统中,为了获得一条指令或者数据,需要三次访问内存。
    第一次访问,是访问内存中的段表,从中获取页表的地址;
    第二次访问是访问内存中的页表,从中获取该页所在的物理块号,并将该块号和页内地址,一起形成指令或数据的物理地址;
    第三次才是真正的访问第二次访问所得的地址,取得指令或者数据。

    相关文章

      网友评论

          本文标题:iOS 内存管理(一)

          本文链接:https://www.haomeiwen.com/subject/ninpqrtx.html