程序装载的问题
Posted ᝰFour Years
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序装载的问题相关的知识,希望对你有一定的参考价值。
前言
在上面我们说过了程序在变成机器码的时候。需要通过装载器装载到内存中去,但是这其中还是有很多问题的,主要是以下两点
- 可执行程序占用的空间应该是连续的,因为程序要一条条的往下执行,所以指令应当连续的储存在一起
- 同时需要加载很多的程序,我们不能让程序自己选择加载到哪。计算机同时会运行多个程序,你不能规定他的地址、
为了解决这些问题,我们提出了虚拟内存来概念来解决这个问题
在我们执行的程序中,我们看见的都是他的虚拟内存,而我们也只需要去关注他的虚拟内存即可。在不同的程序中,我们可能会看到相同的内存地址,但是他们并不冲突。我们会维护不同的内存映射表,通过虚拟内存找到他的真实物理内存,这样执行出来的就是连续的地址空间。 同样的,我们为了减少系统的损耗,我们只用去维护他的起始地址和终止地址即可。
内存分段
下面就来详细的说说这个到底是怎么完成的,首先来说这个内存分段的问题,分段就是找出一片连续的物理内存和虚拟内存进行映射,段其实就是系统分配出来的连续内存空间。
但是这种方式会有一个问题,就是他会产生内存碎片,导致空间利用率非常的低
我们来看这样一个例子。我现在手头的这台电脑,有 1GB 的内存。我们先启动一个图形渲染程序,占用了 512MB 的内存,接着启动一个 Chrome 浏览器,占用了 128MB 内存,再启动一个 Python 程序,占用了 256MB 内存。这个时候,我们关掉 Chrome,于是空闲内存还有 1024 - 512 - 256 = 256MB。按理来说,我们有足够的空间再去装载一个 200MB 的程序。但是,这 256MB 的内存空间不是连续的,而是被分成了两段 128MB 的内存。因此,实际情况是,我们的程序没办法加载进来。
当然,我们解决这个问题的方式就是内存交换,我们可以把python那段程序读到硬盘上,然后重新的分配空间,紧跟在上面512M的空间后面就解决了这个问题。如果你自己安装过 Linux 操作系统,你应该遇到过分配一个 swap 硬盘分区的问题。这块分出来的磁盘空间,其实就是专门给 Linux 操作系统进行内存交换用的。
但是内存交换也有着问题,就是将程序写入磁盘,之后再将磁盘的数据写回内存需要花费大量的时间。如果是很大的程序还会导致机器变的卡顿。
内存分页
从上面我们知道了问题就是出在了交换的空间过多,所以我们又引出了内存分页这个概念,我们将一个程序分为许多固定的大小,而对应的虚拟内存也会被分为固定的大小,这样一个大小相同且空间连续的空间我们称为页
这样由于空间都是预先设定好的,就没有了不能使用的碎片,而只有被释放出来的页,在程序运行的时候,即使内存不够,也能交换出来一些页来(内存分页,在虚拟内存中是很多连续的页,而在物理内存中页的地址不一定是连续的,这解决了内存碎片的问题,同时程序运行的时候,并不需要一次加载完所以的内存,而是用到什么才去加载什么)
注:在上面的页的数据从硬盘到内存的过程中就是使用了内存交换技术
实际上,在操作系统中我们也是这样子去做的,当需要读取特定的页的时候,发现数据并没有加载到物理内存中的时候,会触发一个来自CPU的缺页错误,我们的操作系统会捕捉到这个错误,并将对应的页读到物理内存中,这样就使我们可以去运行那些远大于我们实际内存的程序了,任何程序都不需要一次性的加载完所有指令和数据,只需要加载当前能使用的就好。
通过虚拟内存,内存交换和内存分页三个技术组合,我们最终让一个程序不用考虑他的实际物理内存地址,大小很分配方案,任何程序只需要将内存当作一块完整而连续的空间使用即可,这也是我们计算中常用的一种方式,加入一个间接层
以上是关于程序装载的问题的主要内容,如果未能解决你的问题,请参考以下文章