物理内存 虚拟内存 页映射模式

简介: 物理内存 虚拟内存 页映射模式

链接:


虚拟内存和物理内存

虚拟内存到物理内存的映射


虚拟内存的由来:


在早期的计算机中,是没有虚拟内存的概念的。我们要运行一个程序,会把程序全部装入内存,然后运行。

当运行多个程序时,经常会出现以下问题:

1.进程地址空间不隔离,没有权限保护。

  由于程序都是直接访问物理内存,所以一个进程可以修改其他进程的内存数据,

  甚至修改内核地址空间中的数据。

2.内存使用效率低

  当内存空间不足时,要将其他程序暂时拷贝到硬盘,然后将新的程序装入内存运行。

  由于大量的数据装入装出,内存使用效率会十分低下。

3.程序运行的地址不确定

    因为内存地址是随机分配的,所以程序运行的地址也是不确定的。

    我们都知道,每个程序被运行起来后,它将拥有自己独立的线性空间,这个线性空间由cpu的位数决定,比如32位硬件平台决定了线性地址空间的寻 址空间为02^32-1,即0x000000000xFFFFFFFF,也就是4GB大小。如果每个进程都有4GB,那我们的内存根本就不够用。其实,这4GB并不是真正的内存空间,它是虚拟内存空间,顾名思义,之所以称为虚拟内存,是和系统中的物理内存相对而言的,它是操作系统内核为了对进程地址空间进行管理而设计的一个逻辑意义上的内存空间概念。我们程序中的指针其实都是这个虚拟内存空间中的地址。虚拟内存是将系统硬盘空间和系统实际内存联合在一起供进程使用,给进程提供了一个比内存大的多的虚拟空间。在程序运行时,只需要把虚拟内存空间的一小部分通过页映射模式,经过MMU部件转换映射到物理内存即可。

    那么这4GB的空间是不是就由该进程随意使用呢?遗憾的是,不可以。因为操作系统需要监控进程,进程只能使用那些操作系统分配给它们的地址,如果访问未经允许的空间,那么操作系统会捕获到这些访问,将进程的这种访问当作非法操作,强制结束进程。Linux操作系统将进程的4G虚拟空间分配为1:3的结构,1G是操作系统本身,剩下的3G是留给进程使用的。所以在一个进程的眼里,只有操作系统和它自己,就像整个计算机都被它“承包”了。


虚拟内存的重要性


1.CPU操作的数据一般来自于寄存器或者内存,磁盘上的数据是不能直接操控的。而对于内存而言,存放的数据五花八门,形如“HelloWorld.c”的一段程序,除了运行时,他在不在内存对于计算机运行而言没什么所谓。但是形如操作系统尤其是操作系统内核,他必须常驻内存,而且我们需要对他所在的内存加以保护,否则随便一个程序就能修改它所在的内存,对于系统而言非常不安全。

因此我们不能把物理地址直接暴露给程序,而是利用虚拟地址。


2.程序大于内存的状况经常发生,我们需要一种技术能使得在程序大于内存的情况仍能运行该程序。显然此时又是需要到虚拟内存了。使用虚拟内存的计算机,将程序分为固定大小的页。当执行它时,不需要将所有的页都放进内存中,只需要放进当前执行的代码所在的页。


虚拟内存的存在形式


虚拟内存是存在磁盘中的连续的 字节大小的单元组成的一个数组。


2.分页

上述提到的虚拟内存是存在于磁盘中的,虚拟内存会被切分为大小一致的页形式,即虚拟页面(Virtual Page,VP)。同样的,物理内存也被分为大小一致的页形式,称为物理页(Physical Page,PP)虚拟页面和物理页面的大小是相同的,所以我们才可以将虚拟页面映射为物理页面。如下图所示:


494e880f645b46ae8bd8bcfa7f400924.png


3.页表


我们已经知道了进程是存在于虚拟内存中的,然后将其一页一页地映射到物理内存上。那么计算机怎么知道哪一页的虚拟页面映射哪一页的物理页呢?那就是利用页表。


上图是一个页表的基本形式(实际上有更多的位提供更多的功能,这里不赘述)他有一个有效位和n位地址字段构成物理内存的区域组成。每一行可视为一个页表项,将虚拟地址翻译为物理地址需要用到一个页表项。为了使cpu可以简单快速的翻译虚拟地址,一般页表存放在一段连续的内存空间中。

页表常驻内存,当cpu访问到有效位为1的页表项时将其送到cpu内部,经翻译得到物理地址。如果访问到有效位为0的情况,会引起一个缺页中断。

beb1ed77df7d479e88055e6ff7c820f3.png



4.虚拟内存到物理内存的映射过程


此时先记住一个电子器件内存管理单元(MMU,Memory Managament Unit),他是负责地址翻译的器件。在CPU中。

地址翻译的大致流程如下:


49ab2e3bcf61463abf6077cea3d7d45f.png

相关文章
|
24天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
42 6
|
2月前
|
缓存 算法 数据处理
如何选择合适的内存访问模式
【10月更文挑战第20天】如何选择合适的内存访问模式
55 1
|
3月前
|
存储 缓存 Linux
用户态内存映射
【9月更文挑战第20天】内存映射不仅包括物理与虚拟内存间的映射,还涉及将文件内容映射至虚拟内存,使得访问内存即可获取文件数据。mmap 系统调用支持将文件或匿名内存映射到进程的虚拟内存空间,通过多级页表机制实现高效地址转换,并利用 TLB 加速映射过程。TLB 作为页表缓存,存储频繁访问的页表项,显著提升了地址转换速度。
|
2月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
62 0
|
3月前
|
存储 安全 Linux
将文件映射到内存,像数组一样访问
将文件映射到内存,像数组一样访问
38 0
|
3月前
|
Linux Shell 虚拟化
使用LiME收集主机物理内存的内容时发生宕机
使用LiME收集主机物理内存的内容时发生宕机
|
3月前
crash —— 获取物理内存布局信息
crash —— 获取物理内存布局信息
|
3月前
|
消息中间件 Linux 容器
共享内存的创建和映射过程
【9月更文挑战第1天】消息队列、共享内存及信号量在使用前需生成key并获取唯一ID,均通过`xxxget`函数实现。
|
28天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
226 1
|
17天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。