系统内存机制

此文章是参考网络上的文章进行总结的,如有不妥请联系删除

什么是内存?

一个软件,一行代码的执行都离不开内存,内存是用来存放CPU运行的数据。当我们编写完一个程序之后,将其编译成为二进制可执行文件。而二进制文件是存储在硬盘中的。那么程序是如何运行起来的呢?当我们点击可执行文件之后,首先会将可执行文件加载到内存中,CPU逐句的将命令进行计算和处理。因此内存在计算机的运行,程序的加载有不可替代的意义。

内存(Memory)是计算机的重要部件之一,也称内存储器主存储器,它用于暂时存放CPU中的运算数据,与硬盘外部存储器交换的数据。它是外存CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。只要计算机开始运行,操作系统就会把需要运算的数据从内存调到CPU中进行运算,当运算完成,CPU将结果传送出来这个解释来自于百度百科)。

需要注意的是内存中的数据断电或者关机都会被清除

  1. 内存的分类

内存一般分为三种:只读存储器ROM、随机存储器RAM、高速缓冲存储器(Cache Memory)。

只读存储器(ROM)顾名思义,是只能用来读的存储器。

随机存储器(RAM)就是我们常说的计算机内存,也就是我们常说的内存条。随机存储器以一般分为两种,一种是静态随机存储器和动态随机存储器。

高速缓冲存储器(cache),听名字可知,这是一个可以快速存储的存储器。高随缓冲存储器是为了解决CPU和RAM之间读取速率差距的一个存储器。随着CPU的发展,现在大部分高端CPU将高速缓冲器继承到CPU中了。

用户空间和内核空间

用户空间:用户空间指的是应用程序运行的空间,是程序员进行操作的控件

内核空间:内核空间值的是由操作系统和驱动程序运行的。

当程序创建一个进程之后,系统会为此进程分配4G的虚拟内存,用于程序运行所需的资源。那么为啥会是虚拟内存呢?在系统刚开始的时候,由于CPU的功能不是很强大,运行的程序也不多,因此是直接使用物理内存的。但是后来随着CPU的发展,一个CPU可能会同时运行对个程序,这就可能出现某一块内存被两个进程同时操作的可能,出现踩内存的问题,为了解决这个问题,系统出现了分段这个机制,这个机制是将不同进程通过分段映射的方式映射到物理内存上。刚开始的分段是将物理内存分配为固定大小的内存块,但这样分派会出现很多的内部内存碎片,而且后来CPU的功能发展的越来越强大,可以运行的进程越来越多,如果每一个进程都采用实际的物理内存的话,很明显物理内存是不够的,而且将会浪费很多CPU的资源,要知道,CPU的处理速度是ns级别的,而内存的处理速度是ms级别的。因此为了最大程度的利用CPU的资源,实现多进程多任务的功能。因此系统就采用虚拟内存,通过映射的机制,将运行的进程的一部分映射到物理内存,而一部用的是虚拟内存,当要运行时,在将虚拟内存映射到物理内存上。

还有一个问题,那就是用户空间是如何使用内核空间的,我们都知道我们编写的程序最后都是调用执行的物理器件,而控制物理器件算法和程序都是在内核空间中,那么用户空间时如何调用内核空间中呢?

其实用户空间调内核空间有一下几种方式:系统调用和硬件中断

系统调用就是用户空间调用一些系统函数,例如打开设备的open、write、read等函数。

硬件中断就是硬件本身产生的中断。

虚拟内存和物理内存的关系。 

虚拟内存:虚拟内存指的当系统中一个进程启动的时候,系统会给其分配4G的虚拟空间,用于进程的执行,但是最终还是要映射到物理内存中。虚拟内存就是我们平时在编程果真使用malloc开辟,free释放的内存。我们程序编写过程所谈及的内存都是虚拟内存。

物理内存:物理内存就是我们能看到的实实在在的内存,也就是我们平时所说的内存条或者运存。他们两者的关系是一种映射关系,前面也说过,为了解决CPU资源的浪费和运行更多线程,将物理内存的虚拟内存的一部分映射到物理内存,通过CPU的调度,达到更多进程的运行和CPU资源的最大化利用。

虚拟内存和物理内存的映射机制

段式管理

     段式管理就是将内存分成一段一段的,以段为单位进行管理。

那么什么是段??

:程序编制的程序可以由一个主程序、若干个子程序、符号表、栈以及数据等若干段组成,每一段都有独立、完整的逻辑意义。是不是换是有点模糊,通俗的说就是程序中的函数就是一个段。

知道了段,我们还需要知道段表,因为段表示将虚拟地址和物理地址映射起来的。也可以将段表理解为段式管理的主要核心内容。因为没有段表,将无法实现虚拟内存和物理内存的映射。

那什么是段表??

段表简单点理解就是一个表,里面存储了段号、段寄地址和段界限。

段号:是指虚拟内存需要访问的物理内存所在的段,相当于段索引。

段基地址:是对应段的首地址

段界限是对应段内存的范围。例如段基地址为0x00000000,如果段界限为100,那么此段就不能访问超过0x00000100的地址,如果访问超过则会报错。

段式管理映射原理:

知道了段和段表,我们就来说一下原理。

在段式管理中,虚拟内存分为高16位和低16位,高十六位为段号,低十六位为段内偏移。因此在段式管理中段号有2^16个,段内最大偏移为2^16。

当以虚拟地址需要映射到物理内存的时候,首先会根据虚拟地址中的段号,在段表中获取对应的段基地址,获取到段基地址之后,将段基地址和段内偏移进行相加就可以得到对应的物理地址。

这时候是不是发现段界限好像没有用,是不是有这种疑惑。

段界限的作用就是判断段偏移是否超出范围,因为前面说过段的大小是不确定的,因此需要使用段界限进行隔离,如果偏移地址超出段界限的大小,系统就会报错。

如下图所示:

假如有三个进程,每一个进程有两个段。下图就是虚拟地址和物理地址映射的过程。

如果进程1中的第一段对应的是段号为0,它需要的大小为10k,首先会在物理内存中找对应大小的内存进行分配,如果没有则会找一块空闲的内存进行分配,分配相应大小的内存,然后将首地址和段界限存储在在段表中。加入分配之后的段基地址为0xffff0001,它的段界限为10k也就是0x2800。它的地址分配好了之后,那下一步就是寻址了,将虚拟地址映射到物理地址。这个过程就简单了,首先是虚拟地址,假如虚拟地址为0x00000000 00000200,那么首先它的高16位为0,因此对应的段号为0,在段表里面0段对应的基地址是0xffff0001,因此段基地址加上虚拟地址的低16位为段内偏移。接下来就是判断段内偏移是否小于段界限,这里段内偏移为0x0200,段界限为0x2800。这个地址是可以访问的,因此将段基地址和段内偏移相加得到物理地址0xffff0001+0x0200 = 0xffff0201,此地址就是对应的0x00000000 00000200虚拟地址的物理地址。

段式管理的优点和缺点:

优点:解决了固定分配内存产生内部碎片的问题。(固定分配就是将物理内存分为固定大小的内存块,这样如果使用内存的大小小于固定内存分配的大小,那么就会产生一些内部碎片,造成内存的发浪费。而且固定大小的内存如果有一个进程需要的内存大于固定内存,则会拒绝用户的内存分派)。

缺点:虽然解决的固定内存分派的方式产生的内部碎片,但是会产生外部碎片。那么外部碎片是如何产生的,举个例子,假如现在有三个段式相邻的,加入第一个段占用的内存为10K,第二段占用的内存为20k,第三段占用的内存为10K。在程序的运行过程中,假如第二段的内存已经释放了,但是第一段个第三段的内存没有释放,现在有一个进程需要占用30K大小的内存,那么刚释放的内存小于需要的内存,这是系统会重新分派内存,这就会导致刚释放的20K的内存没有得到使用,从而形成外部碎片。

那如何解决外部碎片的问题,这是就引入的页式管理。

页式管理

页是管理和段式管理的思路差不都都是动态分派,通过表将其进行映射,但是页是管理是将分派的内存以页为单位进行分派。

那么什么是页??

页是将虚拟内存和物理内存分成大小相同的块,一个块一般是4K的大小,这个块就称为页,页叫做页框或者页块。

和段一样,段的映射是通过段表,那么同理页的映射是通用页表进行映射的。但是和段映射不一样的是页的映射会有多级页表映射。那么为啥要如此设计,这是因为一个页占有的大小为4K,也就是2^12大小,那么分配的页就有有2^20这么多个,存储如此大的页表会占用很多的内存,而且查找速度也会有影响。因此就有多级映射。

那么页表的结构是咋样的呢??

页表由页号和页基地址组成

页号是用来虚拟地址进行寻找页的,页基地址是用来映射实际的物理地址的。

现在知道了什么是页,页表和页表的组成,接下来我们就理解一下页式映射的原理。

在页式映射的过程中,虚拟地址是由两部分组成,这个和段式映射有点相似。页式映射中虚拟地址是由页号和页基地址组成。当有一个进程需要进行页式映射的时候,会将虚拟内存的页通过页表映射到物理地址,而映射的物理地址的基地址会存储在页表中。这样当需要进行寻址的时候,虚拟地址首先会通过页号在页表中找到对应的页基地址,然后在将页基地址和页内偏移相加就得出实际的物理地址。当然,如果当前所有的页都分配完了,这是还有进程需要分配页,这时候就会启动页式映射的另一个机制,叫做换出和换入。换出就是将内存中长时间没有使用的内存换出到硬盘,而将内存中的页分配给其他进程。而当需要执行换出的内存的时候,就从硬盘中换入到内存中。

到这里,大家有没有发现,段式映射和页是映射其实在逻辑上没有区别,只不过是将段的大小同换成大小相同的页了,那么页式映射是如何减少外部内存的碎片的里,其实道理也很简单,将页固定成大小相同的页,这样加入有一个进程占用了10K的空间,那么它就会分派3个页,当这个10K进程释放之后,在内存中会出现3个页,当有其他进程需要内存时,则可以将这个三个页分配个其他进程。由于页的大小是固定的,因此就不会出现进程需要的空间太大而无法分配的问题,如果这3个页大小不满足此进程的大小,则可以在分配其他的页。不知道细心的同学有没有发现,10K大小的空间却占用了3页,也就是浪费了2K大小的空间。这就是页引入的新问题,内部碎片。但这个内存碎片相当于固定大小分配的内部碎片会少很多。

页式映射还有一个概念,就是当虚拟内存在页表中找不到对应的页时,就会出现缺页的现象,这个时候系统就会产生缺页异常,需要重新分配页表,分配完成之后,页就会存储在页表中。

需要注意的页表示存储在mmu中的。

段页式管理

段页式管理,顾名思义就是同时使用段式管理和页是管理,这个也是Liunx使用的内存管理机制。但是在Linux段基地址都是0开始的,因此Linux实际上是页是管理,只不过是二级页是管理。

段页式管理首先是把内存分段之后在把段分为页,页就是说内存是以段为单位进行管理,而段是以页为单位进行管理的。

段页式的映射过程首先是找到段表在段表中找到页表的地址,通过页表的找到物理地址的基地址,之后通过物理地址的基地址和偏移地址相加就得到物理地址。

这是小编根据网络上的文章进行总结,如果错误欢迎指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值