虚拟内存简述

在远古时期,内存极小,程序也不大,程序直接装载到内存运行。但是随着程序越来越复杂,理所应当的出现了这个问题,

如果程序所需内存比可用内存大,程序该如何运行?

为了解决这个问题,当时提出了一种覆盖装入的技术,就是需要程序员自己把程序分割成若干个不相干的程序块,块与块之间分别装载运行。举个很简单的例子,程序里面有两个主要函数A和B,这两个函数之间没有相互调用关系,当需要A函数运行的时候,就把A函数对应的程序块装载到内存里,等到执行完毕,再装载别的块。

这样的操作不需要把程序全部装入,暂时解决了上面提到的问题。为什么说是暂时解决呢?注意看上面那一段的黑体字部分,这种方法需要程序员自己去理清程序之间的关系,分割程序。程序逻辑相对简单还比较ok,但是当程序更加的复杂,甚至程序代码逻辑调用,根本分不出独立的程序块时,该如何解决?

其实上面那种方法就是现代虚拟内存技术的雏形。

 

要理解虚拟内存,我们先来慢慢理清几个概念,

接下来,我们将理清这3个概念以及它们之间的关系:虚拟地址空间,物理内存空间,虚拟内存。

 

试问,当你在程序中输出一个变量的地址时,这个地址的含义是什么?

试问,你输出一个全局变量的地址,干掉程序,再启动程序,为什么这个地址没有改变?

试问,大家都知道,堆是向上增长,栈是向下增长,那栈和堆之间肯定有一大块地址,这块地址是不是浪费了?

嗯,好好思考一下~

 

不懂虚拟内存,就相当于没学过操作系统。

 

每个进程都会有一个独立的虚拟地址空间,注意,是独立的,相互不能访问的,地址空间里包含了程序运行所需要的全部东西。进程运行时,所需要的所有数据,所有代码,包括内核系统调用,运行库之类的东西,全部取自虚拟地址空间。看到这你可能有疑问了,系统内核只有一个,确定是每个进程独立拥有内核吗?是的,在虚拟空间,每个进程都是独立拥有的,进程所需要的所有东西,都会在虚拟地址空间有独立的地址。

虚拟地址空间是操作系统为每一个程序虚拟化出来的内存空间,虚拟地址空间的大小一般等于内存地址大小,程序装载执行的时候操作系统生成,程序终止的时候消失。程序执行的时候,所有的操作,都是在虚拟地址空间上完成的,物理地址空间对于程序是不可知的状态。程序跟物理地址是完全隔离的。你在程序中输出的变量地址,就是这个变量在虚拟地址空间中的地址。

使用虚拟地址空间的好处:

1.虚拟地址空间是连续的,方便程序执行。

2.各个程序都有自己的一份虚拟地址空间,能隔离各个进程,一个进程中,函数溢出,可能会影响本进程的函数堆栈,但是绝对不会影响到别的进程。

3.节省内存空间。

 

前面还有很多没有交代清楚,比如:

每个进程都有内存那么大的地址空间,内存哪够装啊?

虚拟地址空间中有大块的地方是没有用到的,明明就浪费了空间,为什么说节省内存空间?

 

现在讲一下,虚拟地址空间和物理内存的映射。

在编程中,基本的内存单位应该是字节了,也就是8bit。但是在内存管理中,这个显然太小了,现代操作系统使用页作为内存管理的基本单位,一页大小一般为4K。现在想象一下,整个虚拟地址空间被划分成很多个页,整个物理内存也被划分成很多个页。大家都知道,程序是一条语句一条语句执行的,同一小时间段内,可能程序只会用到几个页的数据,别的页处于闲置状态。事实上,别扯什么虚拟地址空间什么的,代码,数据只有在内存中才能被用到。操作系统做了虚拟地址空间和物理内存的映射,会把即将要用到的虚拟空间页放入内存,不怎么用到的页移除,这个过程进程是感知不到的。进程只跟虚拟地址空间打交道,它用的时候,操作系统准备好了,所以在这个过程对它是无感知的。

地址映射的过程大概就是这样:

程序正在执行,程序的虚拟地址空间一共有10个页,程序执行的时候,操作系统把其中123页映射到物理内存,程序用到了使用虚拟地址空间页面1的时候,使用的是虚拟地址空间的地址,操作系统就把地址映射对应的物理内存页上。再次强调,这个过程中,程序用到的地址都是虚拟地址,只不过操作系统给转换成了物理地址。

等程序把页面1用完了,现在想用页面5,操作系统就会把地址映射到物理内存页对应的5上,但是这个时候,发现内存中没有页面5,这是时候就会触发缺页中断,把一个不怎么用的页淘汰掉(淘汰算法不再赘述),把页面5加载到物理内存中。淘汰掉淘汰到哪了?数据不就丢了?没丢,只是做了个映像,放到了虚拟内存中(也就是磁盘),加载是从哪加载的?从虚拟内存中加载。

 

这个虚拟内存是个啥?

不多说,大概可以理解为,内存页的备份。

从上面的过程可以看出来,虚拟地址空间中的空间,只有用到,才会真实存在(加载到物理内存,或者扔到虚拟内存),如果没用到的话,就什么都没有。就好像一个程序,只用到了10个页,内存中加载了3个,虚拟内存中放了7个,虚拟地址空间很大,但是只有用了才会切切事实存在,比如现在申请了个地址,是第11个页上的,那么这个内存中就扔了一个页出去,把这个页撸进去,这时候,内存中3页,虚拟内存中8页。

 

emmmm,为了描述的方便,我页面是按连续的,要注意实际上的情况,比如虚拟地址空间4个G,也就是2^20 个页,只要访问到哪个页面,哪个页面就会被操作系统弄到内存里,对于程序来说,它就是拥有了所有空间。

 

好了,还有好多东西没有写,比如装载的时候动态库静态库,虚拟地址空间中内存分布模型,操作系统如何实现页面置换的,页表段表,多级映射,elf文件模型,等等

以后可能会慢慢补充,这次大概就写到这里,有什么问题欢迎找我交流

虚拟化是一种将计算机硬件资源抽象成多个虚拟环境的技术,它可以提高计算机系统的利用率和可管理性。虚拟化技术的发展过程大致可以分为以下几个阶段: 1. 软件模拟:在此阶段,模拟器软件会模拟出一个完整的计算机系统,包括处理器、内存、硬盘等,然后在这个模拟器上运行其他操作系统或应用程序。这种方式的缺点是速度较慢,因为需要模拟所有硬件设备。 2. 硬件辅助虚拟化:在此阶段,CPU提供了硬件支持,使得虚拟机可以直接运行在物理硬件上,而不需要通过软件模拟。这种方式的速度更快,但仍然存在一些性能上的损失。 3. 容器化虚拟化:容器化虚拟化是一种轻量级的虚拟化方式,它将操作系统内核和用户空间分离开来,可以在同一主机上运行多个容器,每个容器都有自己的文件系统和网络接口。容器化虚拟化的优点是速度快、资源消耗少,但缺点是容器间隔离性不够好,不能运行不同操作系统。 虚拟化技术的主要特征包括: 1. 隔离性:虚拟化技术可以将不同的虚拟环境隔离开来,避免彼此之间的影响,提高系统的稳定性和安全性。 2. 灵活性:虚拟化技术可以根据需要创建和删除虚拟机,动态调整资源分配,使得系统更加灵活。 3. 高可用性:虚拟化技术可以将虚拟环境迁移到其他物理服务器上,从而提高系统的可用性。 4. 管理性:虚拟化技术可以将多个虚拟环境集中管理,从而提高管理效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值