0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux的虚拟内存究竟是什么?

Q4MP_gh_c472c21 来源:占小狼的博客 作者:zhenbianshu 2021-06-21 16:41 次阅读

前不久组内又有一次我比较期待的分享:”Linux 的虚拟内存”。是某天晚上加班时,我们讨论虚拟内存的概念时,leader 发现几位同事对虚拟内存认识不清后,特意给这位同学挑选的主题(笑)。

之前了解一些操作系统的概念,主要是毕业后对自己大学四年的荒废比较懊恼,觉得自己有些对不起计算机专业出身,于是在工作之余抽出时间看了哈工大在网易云课堂的操作系统公开课,自己也读了一本讲操作系统比较浅的书 《Linux内核设计与实现》,而且去年自己用 C 写简单的服务器时,也追根究底了解了更多的系统底层知识。多亏了这些知识,让我对应用层的知识更有掌控感,也在上次排查问题时助了我一臂之力。

前几天另一位同事来问另一个虚拟内存相关的问题,我才发现对于虚拟内存,我的理解还不够深刻,一些概念还有些矛盾。于是翻一下资料重新整理一下这些知识,希望下次在用到它们时能更顺畅。

由来

虚拟内存

毋庸置疑,虚拟内存绝对是操作系统中最重要的概念之一。我想主要是由于内存的重要”战略地位”。CPU太快,但容量小且功能单一,其他 I/O 硬件支持各种花式功能,可是相对于 CPU,它们又太慢。于是它们之间就需要一种润滑剂来作为缓冲,这就是内存大显身手的地方。

而在现代操作系统中,多任务已是标配。多任务并行,大大提升了 CPU 利用率,但却引出了多个进程对内存操作的冲突问题,虚拟内存概念的提出就是为了解决这个问题。

49bc6f36-d12c-11eb-9e57-12bb97331649.png

上图是虚拟内存最简单也是最直观的解释。

操作系统有一块物理内存(中间的部分),有两个进程(实际会更多)P1 和 P2,操作系统偷偷地分别告诉 P1 和 P2,我的整个内存都是你的,随便用,管够。可事实上呢,操作系统只是给它们画了个大饼,这些内存说是都给了 P1 和 P2,实际上只给了它们一个序号而已。只有当 P1 和 P2 真正开始使用这些内存时,系统才开始使用辗转挪移,拼凑出各个块给进程用,P2 以为自己在用 A 内存,实际上已经被系统悄悄重定向到真正的 B 去了,甚至,当 P1 和 P2 共用了 C 内存,他们也不知道。

操作系统的这种欺骗进程的手段,就是虚拟内存。对 P1 和 P2 等进程来说,它们都以为自己占用了整个内存,而自己使用的物理内存的哪段地址,它们并不知道也无需关心。

分页和页表

虚拟内存是操作系统里的概念,对操作系统来说,虚拟内存就是一张张的对照表,P1 获取 A 内存里的数据时应该去物理内存的 A 地址找,而找 B 内存里的数据应该去物理内存的 C 地址。

我们知道系统里的基本单位都是 Byte 字节,如果将每一个虚拟内存的 Byte 都对应到物理内存的地址,每个条目最少需要 8字节(32位虚拟地址->32位物理地址),在 4G 内存的情况下,就需要 32GB 的空间来存放对照表,那么这张表就大得真正的物理地址也放不下了,于是操作系统引入了页(Page)的概念。

在系统启动时,操作系统将整个物理内存以 4K 为单位,划分为各个页。之后进行内存分配时,都以页为单位,那么虚拟内存页对应物理内存页的映射表就大大减小了,4G 内存,只需要 8M 的映射表即可,一些进程没有使用到的虚拟内存,也并不需要保存映射关系,而且Linux 还为大内存设计了多级页表,可以进一页减少了内存消耗。操作系统虚拟内存到物理内存的映射表,就被称为页表。

内存寻址和分配

我们知道通过虚拟内存机制,每个进程都以为自己占用了全部内存,进程访问内存时,操作系统都会把进程提供的虚拟内存地址转换为物理地址,再去对应的物理地址上获取数据。CPU 中有一种硬件,内存管理单元 MMU(Memory Management Unit)专门用来将翻译虚拟内存地址。CPU 还为页表寻址设置了缓存策略,由于程序的局部性,其缓存命中率能达到 98%。

以上情况是页表内存在虚拟地址到物理地址的映射,而如果进程访问的物理地址还没有被分配,系统则会产生一个缺页中断,在中断处理时,系统切到内核态为进程虚拟地址分配物理地址。

功能

虚拟内存不仅通过内存地址转换解决了多个进程访问内存冲突的问题,还带来更多的益处。

进程内存管理

它有助于进程进行内存管理,主要体现在:

内存完整性:由于虚拟内存对进程的”欺骗”,每个进程都认为自己获取的内存是一块连续的地址。我们在编写应用程序时,就不用考虑大块地址的分配,总是认为系统有足够的大块内存即可。

安全:由于进程访问内存时,都要通过页表来寻址,操作系统在页表的各个项目上添加各种访问权限标识位,就可以实现内存的权限控制。

数据共享

通过虚拟内存更容易实现内存和数据的共享。

在进程加载系统库时,总是先分配一块内存,将磁盘中的库文件加载到这块内存中,在直接使用物理内存时,由于物理内存地址唯一,即使系统发现同一个库在系统内加载了两次,但每个进程指定的加载内存不一样,系统也无能为力。

而在使用虚拟内存时,系统只需要将进程的虚拟内存地址指向库文件所在的物理内存地址即可。如上文图中所示,进程 P1 和 P2 的 B 地址都指向了物理地址 C。

而通过使用虚拟内存使用共享内存也很简单,系统只需要将各个进程的虚拟内存地址指向系统分配的共享内存地址即可。

SWAP

虚拟内存可以让帮进程”扩充”内存。

我们前文提到了虚拟内存通过缺页中断为进程分配物理内存,内存总是有限的,如果所有的物理内存都被占用了怎么办呢?

Linux 提出 SWAP 的概念,Linux 中可以使用 SWAP 分区,在分配物理内存,但可用内存不足时,将暂时不用的内存数据先放到磁盘上,让有需要的进程先使用,等进程再需要使用这些数据时,再将这些数据加载到内存中,通过这种”交换”技术,Linux 可以让进程使用更多的内存。

常见问题

在了解虚拟内存时,我也有过很多的问题。

32位和64位

最常见的就是 32位和64位的问题了。

CPU 通过物理总线访问内存,那么访问地址的范围就受限于机器总线的数量,在32位机器上,有32条总线,每条总线有高低两种电位分别代表 bit 的 1 和 0,那么可访问的最大地址就是 2^32bit = 4GB,所以说 32 位机器上插入大于 4G 的内存是无效的,CPU 访问不到多于 4G 的内存。

但 64位机器并没有 64位总线,而且其最大内存还要受限于操作系统,Linux 目前支持最大 256G 内存。

根据虚拟内存的概念,在 32 位系统上运行 64 位软件也并无不可,但由于系统对虚拟内存地址的结构设计,64位的虚拟地址在32位系统内并不能使用。

直接操作物理内存

操作系统使用了虚拟内存,我们想要直接操作内存该怎么办呢?

Linux 会将各个设备都映射到/dev/目录下的文件,我们可以通过这些设备文件直接操作硬件,内存也不例外。在 Linux 中,内存设置被映射为/dev/mem,root 用户通过对这个文件读写,可以直接操作内存。

JVM 进程占用虚拟内存过多

使用 TOP 查看系统性能时,我们会发现在 VIRT 这一列,Java 进程会占用大量的虚拟内存。

49ddbcea-d12c-11eb-9e57-12bb97331649.png

导致这种问题的原因是 Java 使用 Glibc 的 Arena 内存池分配了大量的虚拟内存并没有使用。此外,Java 读取的文件也会被映射为虚拟内存,在虚拟机默认配置下 Java 每个线程栈会占用 1M 的虚拟内存。具体可以查看为什么linux下多线程程序如此消耗虚拟内存。

而真实占用的物理内存要看RES(resident) 列,这一列的值才是真正被映射到物理内存的大小。

常用管理命令

我们也可以自己来管理 Linux 的虚拟内存。

查看系统内存状态

查看系统内存情况的方式有很多,free、vmstat等命令都可输出当前系统的内存状态,需要注意的是可用内存并不只是 free 这一列,由于操作系统的 lazy 特性,大量的 buffer/cache 在进程不再使用后,不会被立即清理,如果之前使用它们的进程再次运行还可以继续使用,它们在必要时也是可以被利用的。

此外,通过cat /proc/meminfo可以查看系统内存被使用的详细情况,包括脏页状态等。详情可参见:/PROC/MEMINFO之谜。

pmap

如果想单独查看某一进程的虚拟内存分布情况,可以使用pmap pid命令,它会把虚拟内存各段的占用情况从低地址到高地址都列出来。

可以添加-XX参数来输出更详细的信息

修改内存配置

我们也可以修改 Linux 的系统配置,使用sysctl vm [-options] CONFIG或 直接读写/proc/sys/vm/目录下的文件来查看和修改配置。

SWAP 操作

虚拟内存的 SWAP 特性并不总是有益,放任进程不停地将数据在内存与磁盘之间大量交换会极大地占用 CPU,降低系统运行效率,所以有时候我们并不希望使用 swap。

我们可以修改vm.swappiness=0来设置内存尽量少使用 swap,或者干脆使用swapoff命令禁用掉 SWAP。

小结

虚拟内存的概念非常容易理解,但是它会衍生出来的一系列非常复杂的知识。本文只讲了些基本原理,略过了很多细节,比如虚拟内存寻址中段寄存器的使用,操作系统使用虚拟内存增强缓存、缓冲区的应用等,有机会单独拿出来说。

责任编辑:lq6

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11292

    浏览量

    209327
  • 虚拟内存
    +关注

    关注

    0

    文章

    77

    浏览量

    8058

原文标题:Linux虚拟内存,你理解到位了吗?

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    虚拟内存和云计算的关系

    在现代计算机科学中,虚拟内存和云计算是两个关键的技术概念。虚拟内存是一种内存管理技术,它允许计算机使用比物理内存更多的内存空间,而云计算则是
    的头像 发表于 12-04 09:50 108次阅读

    虚拟内存溢出该怎么处理 虚拟内存在服务器中的应用

    在现代计算机系统中,虚拟内存是一种重要的资源管理技术,它允许系统使用硬盘空间来扩展物理内存的容量。然而,当系统运行的程序和进程超出了物理内存虚拟内存的总容量时,就会出现
    的头像 发表于 12-04 09:49 135次阅读

    Linux下如何管理虚拟内存 使用虚拟内存时的常见问题

    Linux系统中,虚拟内存管理是操作系统内核的一个重要功能,负责管理物理内存和磁盘上的交换空间。以下是对Linux下如何管理虚拟内存以及使
    的头像 发表于 12-04 09:19 353次阅读

    虚拟内存对计算机性能的影响

    在现代计算机系统中,内存管理是确保系统高效运行的关键因素之一。虚拟内存技术作为内存管理的核心组成部分,对于提升计算机性能和用户体验起着至关重要的作用。 一、虚拟内存的概念
    的头像 发表于 12-04 09:17 540次阅读

    什么是虚拟内存分页 Windows系统虚拟内存优化方法

    虚拟内存分页概述 在Windows操作系统中,虚拟内存是通过分页机制实现的。分页允许系统将内存中的数据移动到硬盘上,以便为当前运行的程序腾出空间。这个过程对于保持系统的流畅运行至关重要,尤其是在物理
    的头像 发表于 12-04 09:16 296次阅读

    虚拟内存不足如何解决 虚拟内存和物理内存的区别

    虚拟内存不足的解决方案 虚拟内存不足是计算机用户经常遇到的问题,尤其是在运行大型软件或多任务处理时。以下是一些解决虚拟内存不足问题的方法: 增加物理内存(RAM) : 这是最直接的解决
    的头像 发表于 12-04 09:14 353次阅读

    虚拟内存的作用和原理 如何调整虚拟内存设置

    虚拟内存,也称为虚拟内存管理或页面文件,是计算机操作系统中的一种内存管理技术。它允许系统使用硬盘空间作为额外的RAM(随机存取存储器),以弥补物理内存(RAM)的不足。
    的头像 发表于 12-04 09:13 358次阅读

    PCM1861 INT脚究竟是输出还是输入?

    这个芯片activce或是idle. 是否有人解释下,INT脚究竟是输出还是输入。我希望是输出,我需要读取到是否有analog audio输入的信息。 或者,输入输出与否还要靠其他什么地方设置? 盼望有人回复解答,不胜感激!
    发表于 10-29 07:29

    揭秘贴片功率电感发烫究竟是不是烧坏了

    电子发烧友网站提供《揭秘贴片功率电感发烫究竟是不是烧坏了.docx》资料免费下载
    发表于 09-30 14:44 0次下载

    电感器线径究竟是粗好还是细好

    电子发烧友网站提供《电感器线径究竟是粗好还是细好.docx》资料免费下载
    发表于 09-20 11:25 0次下载

    tas5756m使用GPIO口加内部PLL产生MCLK的方法究竟是怎么样的?

    tas5756m使用GPIO口加内部PLL产生MCLK的方法究竟是怎么样的?
    发表于 08-19 06:06

    请问cH340G的TX引脚电平究竟是3v还是5v?

    用CD34G来实现usb转串口的时候,直接用usb口的5v作为电源电压,它的tx引脚输出的高电平究竟是5v还是3v,我实测是3v,但网上有的人是5v,想进一步得到大家的确认。
    发表于 05-14 08:15

    STM32擦除后数据究竟是0x00还是0xff ?

    STM32擦除后数据究竟是0x00还是0xff ,百度查了许多发现大多数都是0xff的多,都说SD卡(TF)储存介质是Flash 所以擦除后为0xff,但是我遇到了读出来的数据是0x00的情况,为什么呢
    发表于 04-18 07:59

    吸尘器究竟是如何替你“吃灰”的【其利天下技术】

    如今,吸尘器已成为大多数人居家必备的小家电产品,那么说起吸尘器,你对吸尘器有了解多少呢?不知道大家知不知道它的原理是什么?今天我们就来说一说吸尘器究竟是如何替你“吃灰”的。
    的头像 发表于 03-07 21:17 870次阅读
    吸尘器<b class='flag-5'>究竟是</b>如何替你“吃灰”的【其利天下技术】

    Windows服务器虚拟内存的设置建议

    虚拟内存是计算机操作系统用于扩展物理内存的一种机制。在Windows服务器上,虚拟内存的设置对系统性能和稳定性至关重要。以下是关于Windows服务器虚拟内存设置的建议。
    的头像 发表于 12-25 17:03 2477次阅读