操作系统内存及内存管理方式

一、虚拟内存

设想一个场景,如果两个进程都会内存进行写入操作,那么会发生一个问题,进程一在写入完数据后,进程二会将进程一写入的数据给覆盖掉,这是我们非常不愿意看到的,这样会造成程序的崩溃。

为了解决这个问题,必须给每个进程分配不同的内存空间来进行操作,这样不同的进程在执行的时候就不会产生冲突了,而实现这一功能就需要引入虚拟内存。

即操作系统会为每个进程分配一个虚拟内存,操作系统内部会维护一张表,用于记录虚拟内存和实际内存地址之间的映射。这样进程在执行数据写入的时候,操作系统可以通过虚拟地址和实际内存地址之间的映射来确定要操作的内存地址。

 具体过程可以参考这张图。

二、内存分页和内存分段

操作系统为了管理虚拟内存和实际内存之间的关系,采用内存分页和内存分段。

2.1 内存分段

 

内存分段机制下的虚拟地址主要由两部分组成:段选择因子和段内偏移量

可以参考上面这张图,段选择子用于定位段表,进而找到内存中段对应的实际地址的起始地址,而段内偏移量用于定位内存地址在段中的位置 。

也可以这么理解,段选择因子用于定位你住在哪栋楼,段内偏移量用于定位你住在这栋楼的哪一户。

比如我要访问段号3中偏移量为500的内存空间,那么这个内存空间对应的实际物理地址的为7000+500 = 7500。

但内存分段带来两个问题:

一是内存碎片的产生。

二是内存交换的效率较低。

首先来看第一个问题:

 

如图,内存中游戏,浏览器和音乐的程序分别占用512MB,128MB,256MB内存,但浏览器退出后,物理内存中会多处128MB内存,此时一个200MB的新程序试图加入内存中,此时内存中有256MB的空闲空间,理论上来说可以容纳新的程序,但是因为这256MB的内存空间是不连续的,在新程序不支持不连续存储的情况下,无法为其分配内存。

为了给新来的程序分配内存,必须要将内存中的部分程序移出至交换空间,然后才可以为新来的程序分配内存。但这样也会存在一个问题,如果内存交换移出的是一个很大的程序,那么将造成长时间的卡顿,用户体验非常不好。

因此,为了解决内存分段带来的问题,操作系统还有一种内存管理方式,叫做内存分页。

2.2 内存分页

内存分页是把整个虚拟内存和整个内存空间切成一段段固定的大小。将这样连续且尺寸固定的空间成为页。

⻚表是存储在内存⾥的,内存管理单元 (MMU)就做将虚拟内存地址转换成物理地址的⼯作。 

由于内存空间都是预先划分好的,也就不会像分段会产⽣间隙⾮常⼩的内存,这正是分段会产⽣内存碎⽚的原因。⽽采⽤了分⻚,那么释放的内存都是以⻚为单位释放的,也就不会产⽣⽆法给进程使⽤的⼩内存。
如果内存空间不够,操作系统会把其他正在运⾏的进程中的最近没被使⽤的内存⻚⾯给释放掉,也就是暂时写在硬盘上。⼀旦需要的时候,再加载进来。所以,⼀次性写⼊磁盘的也只有少数的⼀个⻚或者⼏个⻚,不会花太多时间,内存交换的效率就相对⽐较⾼。

分页管理下,虚拟地址和物理地址之间的映射方式与分段管理类似。

同样是通过起始地址 + 偏移量的方式来确定。

但简单的分页放在实际的操作系统中运行是会有问题的。因为页的内存空间大小相对较小,页表的大小较大,因此占用了大量的内存空间。于是出现了多级页表和段页式管理。

2.3 多级页表

多级页表的结构如图所示,一级页表中将不再存储页号信息而是存储着二级页表的地址,二级页表也将存储着下一级页表结构的地址,直到最后一级页表中会存储着对应的物理页号。

可以把多级页表理解为树结构,下级页表是上级页表的子结点,物理页号存储在叶子结点中。

只有在子页表结构中有存储物理页号时,才会创建这个子结点,否则,将不进行子结点的创建,这样将大大节省内存空间。

2.4 段页式管理

如图所示,段页式管理的原理如下:

1.先将内存划分成多个段

2.将每个段划分成多个页

3.通过段表映射到每个段对应的段页表

4.通过每个段对应的段页表查找到物理内存中的对应地址。

 三、linux系统中的内存管理

linux中的内存结构如下:

通过这张图你可以看到,⽤户空间内存,从低到⾼分别是 6 种不同的内存段:
1.程序⽂件段,包括⼆进制可执⾏代码;
2.已初始化数据段,包括静态常量;
3.未初始化数据段,包括未初始化的静态变量;
4.堆段,包括动态分配的内存,从低地址开始向上增⻓;
5.⽂件映射段,包括动态库、共享内存等,从低地址开始向上增⻓(跟硬件和内核版本有关);
6.栈段,包括局部变量和函数调⽤的上下⽂等。栈的⼤⼩是固定的,⼀般是 8 MB 。当然系统也提供了参数,以便我们⾃定义⼤⼩; 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值