> For the complete documentation index, see [llms.txt](https://androidsummary.gitbook.io/androidsummary/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://androidsummary.gitbook.io/androidsummary/handlemenmory/operating_system_basis.md).

# Android内存管理(操作系统基础)

## 操作系统基础

这里不在详细的讲解操作系统,只是介绍关于内存的几个关键名词及相关概念:

* 物理内存
* 虚拟内存
* 逻辑地址
* 交换空间

如果的比较熟悉上述几个关键名词,此章节可以跳过

### 物理内存(RAM)：

加载到内存地址寄存器中的内存又叫“硬件内存”，是内存单元真正的地址(也叫物理地址)。RAM作为进程运行不可或缺的资源，对系统和稳定性有着决定性的影响。另外，RAM的一部分被操作系统留作他用，比如显存等。

## 逻辑地址:

由CPU控制生成的地址，是一个程序级别的概念。这里引用一个浅显的例子——我们在C语言指针编程中，可以读取指针变量本身的值(&操作)，这里取得的值就是逻辑地址——也就是说，这个(&操作)取得的值是CPU控制生成的一个逻辑地址，并不是这个指针变量在RAM中的真正地址。 那么，我们为什么要这么一个并不是真正地址的逻辑地址呢？深层次的原因这里不予以探究，但是一个比较浅显的原因就是，逻辑地址的分配非常灵活——在一个数组中，我们通过逻辑地址可以保证数组中元素地址的连续性。当然这个逻辑地址最终还是要通过一定的方式映射到RAM中的物理地址上，这个物理地址才是元素存储的真正地址，而这个物理地址，不一定是连续的。

### 虚拟内存：

是操作系统级别的概念，指计算机呈现出要比实际拥有的内存大得多的内存量。它使得每个应用程序都认为自己拥有独立且连续的可用的内存空间（一段连续完整的地址空间），这个内存大小跟操作系统的位数有关。比如32位系统，逻辑内存的最大为2^32。而实际上，它通常是被映射到多个物理内存段（在真正的物理地址上不一定是连续的），还有部分暂时存储在外部磁盘存储器上，在需要时再加载到内存中来。 上一段我们我们说了半天的逻辑地址，理解就是虚拟内存中的地址。OK，现在我们知道了虚拟内存有两个特点——一个是在虚拟内存中虚拟地址/逻辑地址是连续的，便于灵活分配；二是虚拟内存可以是计算机呈现出比实际内存大的多的内存。那么为什么虚拟内存会呈现出这么大的内存的神奇功能呢？或者说这多出来的额内存是哪来的？这就要用到我们接下来讲的交换(Swap)空间。

## 交换(Swap)空间：

在系统中运行的每个进程都需要使用到内存，但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存，内核会释放某些进程所占用但未使用的部分或所有物理内存，将这部分释放的数据存储在磁盘上直到进程下一次调用，并将释放出的内存提供给有需要的进程使用。 引用一个容易理解但不是很恰当的比喻：你不需要很长的轨道就可以让一列火车从上海开到北京。你只需要足够长的铁轨（比如说3公里）就可以完成这个任务。采取的方法是把后面的铁轨立刻铺到火车的前面，只要你的操作足够快并能满足要求，列车就能象在一条完整的轨道上运行。 swap和虚拟内存结伴而来的。如果系统是64位，最大虚拟内存可以是2的64次方，没有计算机会有这么大的内存。当内存不够用的时候只能映射到磁盘。linux专门开辟了一个swap磁盘分区，当物理内存不够用的时候(程序并不知道)，将内存中很久不使用的内存区域交换到swap区。也即是说：用作虚拟内存的磁盘空间称为交换空间（swap空间）。

## 分析:32位系统最大只能支持4GB内存原因

大家肯定都看过自己系统的内存，估计大家都遇到过下面的情况(都是32位系统):

* 自己装的是4G内存条，可是操作系统显示的内存却是3.75G
* 自己装的是8G内存条，可是操作系统显示的内存也是3.75G

上面这两种情况为什么呢，下面分析其中的缘由，在分析缘由之前，先了解下计算机系统结构方面的知识。

### 1.认识计算机总线

其实大家在生活中经常用到总线，就是USB接口，其实就是一种总线，叫做USB总线。

#### 1.1 为什么需要总线

![冯诺伊曼计算机结构](https://upload-images.jianshu.io/upload_images/1329440-bcd6bd4dc799c99b.png?imageMogr2/auto-orient/strip|imageView2/2/w/514/format/webp)

上图是冯诺依曼计算机结构图,由五大部分组成: 逻辑运算器、控制器、存储器、输入设备、输出设备

如果输入或者输出设备想把数据存储到存储器或者从存储器取数据，则需要通过逻辑运算器(CPU中)，则CPU会停止工作，影响CPU的效率，为了提高CPU工作效率，出现了总线的概念。

![总线结构图](https://upload-images.jianshu.io/upload_images/1329440-d53e7d008bf705ba.png?imageMogr2/auto-orient/strip|imageView2/2/w/816/format/webp)

上图是计算机中的一种总线结构，如果想了解更多的总线设计结构，可以查看计算机组成原理相关书籍，这里主要是为了说明为什么需要总线。

总线是连接多个部件的信息传输线，是各部件共享的传输介质。输入输出设备可以和主存通信而不用影响CPU的工作，这样CPU的工作效率得到了很大的提升。

* 系统总线: 用于IO接口、主存、CPU之间的信息传输，IO和CPU之间只传输指令信息。
* 主存总线: 专门用于主存和CPU之间的信息传输

#### 1.2 系统总线的分类

* 数据总线：

数据总线用来传输各功能部件之间的数据信息，它是双向传输总线，其位数就是数据总线的宽度。总之是用来传输数据的。

* 地址总线：

地址总线主要用来指出数据总线上的源数据或目的数据在主存单元的地址或者I/O设备的地址。总之就是传输数据所在地址。

* 控制总线：

由于数据总线、地址总线都是被挂在总线上的所有部件共享的，如何使各部件能在不同时刻占有总线使用权，需依靠控制总线来完成，因此控制总线是用来发出各种控制信号的传输线。总之是用来传输控制指令的。

### 2.分析问题缘由

问题：

* 自己装的是4G内存条，可是操作系统显示的内存却是3.75G
* 自己装的是8G内存条，可是操作系统显示的内存也是3.75G

在使用计算机时，其支持的最大内存是由操作系统和硬件两方面决定的。

**硬件方面**：

上面介绍总线的时候已经介绍了地址总线，是用来传输数据所在地址的，而32位系统一般有32根地址总线，那么所能传输的最大数据地址就是2^32，这里所指的地址是真实的数据地址，即物理地址，CPU在执行指令时需要先将指令的逻辑地址变换为物理地址才能执行。

|       | 地址总线数目 | 最大支持内存                            |
| ----- | ------ | --------------------------------- |
| 32位系统 | 32     | 2的32次方 = 4G                       |
| 64位系统 | 36或40  | 2的36次方 = 64G 或 2的40次方= 1024G = 1T |

**系统方面**：

用户在使用计算机时能够访问的最大内存不单是由CPU地址总线的位数决定的，还需要考虑操作系统的实现。实际上用户在使用计算机时，进程访问到的地址都是逻辑地址，并不是真实的物理地址，逻辑地址是由操作系统提供的，并维护了逻辑地址和物理地址的映射。

对于32位的windows操作系统，提供的逻辑地址寻址范围是4G，但是对于这4G的逻辑地址，又要划分出来一份给CPU寄存器、ROM的这些物理地址进行映射，那么剩下和内存条的物理地址进行映射的空间肯定没有4G了,如下图所示:

![](https://upload-images.jianshu.io/upload_images/1329440-ea55740fd9874f7c.png?imageMogr2/auto-orient/strip|imageView2/2/w/600/format/webp)

其实操作系统显示的内存3.75G，是逻辑地址。
