浅谈C语言的虚拟内存

浅谈C语言的虚拟内存

​ 学过C语言后可知,在C语言中,指针变量就是一个内存地址, &运算符的作用也是取变量的内存地址。

​ 如果我们运行的程序较多,占用的空间就会超过内存(内存条)容量。例如计算机的内存容量为2G,却运行着10个程序,这10个程序共占用3G的空间,也就意味着需要从硬盘复制 3G 的数据到内存,这显然是不可能的。

操作系统为我们解决了这个问题:当程序运行需要的空间大于内存容量时,会将内存中暂时不用的数据再写回硬盘;需要这些数据时再从硬盘中读取,并将另外一部分不用的数据写入硬盘。这样,硬盘中就会有一部分空间用来存放内存中暂时不用的数据。这一部分空间就叫做虚拟内存。

3G - 2G = 1G,上面的情况需要在硬盘上分配 1G 的虚拟内存。

以代码为例子:

#include <stdio.h>
#include <stdlib.h>
int a = 0, b = 1;
int main(){
    int *pa = &a;
    printf("pa = %#X, &b = %#X\n", pa, &b);
    system("pause");
    return 0;
}

​ 在Visual studio下运行结果为:

​ pa = 0X12AA140, &b = 0X12AA000

​ 了解C语言编译过程的话,可知在链接的过程时,代码中变量的内存地址就已经被决定好了。

​ 但内存就那么多,如果物理内存中这两个地址被其他程序占用了怎么办?

​ 其实这些内存都是假的,是虚拟内存,不是真实的物理内存地址。虚拟地址要经过CPU的转换才能对应到物理地址,而且每次程序运行时,操作系统都会重新安排虚拟地址和物理地址的对应关系,哪一段物理地址空闲就用哪一段。

​ 比如说上面代码的内存地址:0X12AA140、0X12AA000,经过CPU的内存映射机制后,可能对应的物理地址就是0X03BB100、0X562C203。这些物理地址不是我们程序需要关心的地方,交给CPU去处理就好了

​ 说白了,虚拟内存就是:**把程序给出的地址看做是一种虚拟地址,然后通过某些映射的方法,将这个虚拟地址转换成实际的物理地址。**这样,只要我们能够妥善地控制这个虚拟地址到物理地址的映射过程,就可以保证程序每次运行时都可以使用相同的地址。

那么为什么要使用虚拟内存呢?

·可以使不同程序的地址空间相互隔离

​ 如果所有程序都使用物理内存,那么程序所使用的空间就不是相互隔离的。比如说一段连续的内存保存了几个数据,如果这时有恶意程序运行的话,就可以很轻易的改写其他程序的内存数据。

​ 使用了虚拟地址后,程序A和程序B虽然都可以访问同一个地址,但他们对应的物理地址是不同的,这样就不会修改到对方的内存。

·提高内存的使用效率

使用虚拟地址后,操作系统会更多地介入到内存管理工作中,使得控制内存权限成为可能。例如,我们希望保存数据的内存没有执行权限,保存代码的内存没有修改权限,操作系统占用的内存普通程序没有读取权限等。

​ 另外,当物理内存不足时,操作系统能够暂时控制不需要的内存换入换出。磁盘 I/O 是非常耗时的工作,这能够从很大程度上提高程序性能。这里涉及到**内存的分页机制**。

·中间件思想

​ 在计算机中,为了让操作更加直观、易于理解、增强用户体验,开发者经常增加中间层,即**使用一种间接的方式来屏蔽复杂的底层细节,只给用户提供简单的接口。**虚拟地址是使用中间层的一个典型例子。

从汇编到高级语言,从直接操作硬件到开发操作系统,这些都是中间件思想。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值