赞
踩
首先明确下面几个概念:
程序和进程并不是一一对应的。一段程序可以在不同的数据集上形成多个不同的进程,也可以因为没被执行而不产生进程。但进程一定有一段对应的程序。
Linux系统内存管理的职责是:进程请求内存时分配可用内存,进程释放内存时回收内存,跟踪系统内存的使用情况。
物理内存:就是内存条提供的物理存储空间,主板上的内存条提供多大的存储空间,物理内存就有多大。
物理地址:内存条中的存储单元的真实地址,编号从0开始一直到物理存储单元的最高端。
早期的操作系统没有虚拟内存概念的时候,程序寻址都使用物理地址。在32位平台下,CPU的寻址范围是2^32也就是0~4G。对于多个进程并发执行的操作系统,如果为每个进程都分配4G的物理内存,会产生很多问题,例如
1.物理内存是有限的,不足以为每个进程都提供4G的运行空间,没分配到空间的进程只能在内存外等待,十分没有效率。
2.由于每个程序都使用物理地址进行访问,相互没有隔离,导致一个进程可以通过物理地址直接修改另一个进程的数据,十分不安全
3.由于每次程序运行时被装入内存的位置是不固定的,但程序中物理地址是写死的,因此访问不到正确的数据。
为了解决上述问题,虚拟内存应运而生。
虚拟内存:在系统中,每个进程都认为自己得到了4G连续的地址空间。实际上这份空间并不是真正的内存空间,它通常被分割成很多各物理内存碎片,乱序的存放在物理内存条中,甚至有一些因为内存有限只能存放在磁盘存储器上,在必要时再被装入内存。
逻辑地址:现代程序内部使用的地址都是逻辑地址,也就是数据在进程的4G虚拟内存中的地址。逻辑地址当然也是虚拟的。
所有进程共享同一块物理内存,逻辑上各自拥有一块连续的虚拟内存。当一个进程要访问某个数据时,会给出该数据的逻辑地址。系统使用地址映射算法将逻辑地址转换成物理地址,再访问物理内存中相应的存储单元取得数据。
为了方便逻辑地址到物理地址的映射,大多数操作系统都使用了页式的内存管理机制,通过页的映射来实现逻辑地址到物理地址的转换。
在页式内存管理体制中,页(Page)是内存管理的基本单元。Linux中一个页的默认大小为4KB。
每个进程都有独自的虚拟内存4G,可被分成4G/4K=1M个页。将这些从0开始编号。
将物理内存也以4K为一个单位进行管理,每个单位可被称为页框或块,将页框也从0开始进行编号。
为每个进程都建立一张表,用来存储该进程每个页加载到物理内存的哪个页框中,这样的表称为页表。页表中的每一项都是页到页框的映射,称为页表项。
每个进程有4G的虚拟内存,通常将0~3G划分为用户空间,3 ~ 4G划分为内核空间。
用户进程可以直接访问用户空间,每个进程都有自己独立的用户空间。
用户进程不能直接访问内核空间,通过系统调用或异常操作才能访问内核空间。所有进程共享内核空间。
一个进程的虚拟内存可以大致进行如下划分:
注意:这是一个大致的划分,实际上Linux划分得更细
用户空间被大致划分为代码段、数据段、BSS段、堆段、栈段这五个段,每个段得作用如下:
内核空间被大致分为ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM三个区域,每个区域的作用如下:
vmalloc()函数使用的是ZONE_HIGHMEM的空间,通常用来申请大块的内存空间,且逻辑地址连续的空间物理地址不一定连续。kmalloc()函数使用ZONE_NORMAL中的空间,可以以字节为单位进行分配,通常用来申请小块的内存空间,且逻辑地址连续的物理地址一定连续。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。