今天给大家分享Linux虚拟内存相关的知识,希望的对大家能有所帮助!

1、虚拟内存

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

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

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

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

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

2、分页和页表

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

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

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

3、内存寻址和分配

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

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

4、功能

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

5、进程内存管理

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

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

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

6、数据共享

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

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

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

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

7、SWAP

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

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

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

8、常见问题。

8.1 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位系统内并不能使用。

8.2 直接操作物理内存

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

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

8.3 JVM 进程占用虚拟内存过多

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

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

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

8.4 常用管理命令

我们也可以自己来管理 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。

小结


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

IT技术分享社区

个人博客网站:https://programmerblog.xyz

文章推荐程序员效率:画流程图常用的工具程序员效率:整理常用的在线笔记软件远程办公:常用的远程协助软件,你都知道吗?51单片机程序下载、ISP及串口基础知识硬件:断路器、接触器、继电器基础知识

操作系统:Linux虚拟内存知识介绍相关推荐

  1. 操作系统——Linux 虚拟内存和物理内存的理解

    虚拟内存: 第一层理解 1..每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构: 2.一个新进程建立的时候,将会建立起自己的内存空间,此进程的数据,代码等从磁盘拷贝到自己的进程空间 ...

  2. 『Linux基础 - 2 』操作系统,Linux背景知识和Ubuntu操作系统安装

    这篇笔记记录了以下几个知识点: 1.目前常见的操作系统及分类,虚拟机 2.Linux操作系统背景知识,Windows和Linux两个操作系统的对比 3.在虚拟机中安装Ubuntu系统的详细步骤 OS( ...

  3. 操作系统linux配置php,操作系统--Linux的详细介绍

    一 概述 1.什么是操作系统? 操作系统是人与计算机硬件交互的中介.用户无法直接与计算机硬件交互,无法直接指挥计算机工作,因此需要一个中介,这个中介就是操作系统,用户向操作系统发出命令,由操作系统直接 ...

  4. linux云计算架构师运维笔记-第1天-硬件知识介绍与操作系统部署

    linux云计算架构师运维笔记-第1天-硬件知识课程说明 1. 课程知识详细讲解 1.1 服务器硬件知识介绍 1.1.1 硬件设备种类介绍部分 1.1.2 企业服务器运行指标: 1.1.3 服务器种类 ...

  5. ncl与linux的关系,研会活动 | 大气院研究生会举办Linux操作系统及NCL知识讲座

    原标题:研会活动 | 大气院研究生会举办Linux操作系统及NCL知识讲座 为帮助研一同学熟悉Linux操作系统以及NCL等常用科研工具,尽快进入科研状态,10月19日晚上7点,大气院研究生会在气象楼 ...

  6. Linux虚拟内存介绍,以及malloc_stats和malloc_info 监控查看内存情况

    Linux虚拟内存介绍,以及malloc_stats和malloc_info 监控查看内存情况 zzhongcy 2019-04-09 10:33:08 3106 已收藏 3 分类专栏: Linux ...

  7. 从零学Linux第一章——操作系统演变及历史介绍

    操作系统演变及历史介绍 操作系统的目标 方便:使计算机系统易于使用 有效:以更有效的方式使用计算机系统资源 扩展:方便用户有效开发.测试和引进新功能 操作系统的功用: 进程管理/内存管理/文件 ...

  8. Linux 操作系统编程基础知识

    Linux操作系统 1.Linux 操作系统编程基础知识 1.3 系统调用和库函数 1.3.1 接口 命令接口:以命令形式呈现在用户面前,方便用户直接或间接控制自己的作业. 程序接口:为应用程序使用系 ...

  9. 操作系统:SSH协议知识介绍

    今天给大家分享SSH协议相关的知识介绍,希望对大家能有所帮助! 1.SSH协议概念介绍 SSH(Secure Shell)安全外壳协议,是一种建立在应用层基础上的安全协议,通过对密码进行加密传输验证, ...

最新文章

  1. Mail Archiving Expert电子邮件归档专家
  2. Kaggle大神:竞赛代码别删,这都是宝藏
  3. 如何选择就业方向(80后的个人经验,转载)
  4. 深入解析NoSQL数据库的分布式算法
  5. opencv4 c++ 提取图片中的白色区域_【从零学习OpenCV 4】形态学应用
  6. 游戏行业DDoS 6年谈:什么样的架构才可以对DDoS免疫?
  7. 给Ubuntu 16.04更换更新源
  8. 变量的定于[指针/函数指针]
  9. HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题...
  10. linux connect 阻塞超时时间,在linux下玩转带有超时时间的connect函数
  11. jQuery与JavaScript与ajax三者的区别与联系
  12. mysql引擎与操作系统的关系_mysql五大引擎之间的区别和优劣之分
  13. 开发环境搭建3:linux下tuxedo安装
  14. git无法上传大文件
  15. TestNG官方文档中文版(1)-介绍
  16. 关于node.js,dataStr的undefined的问题
  17. 如何在视频上添加水印?建议收藏这些方法
  18. c语言编写坦克大战设计报告,c语言编写坦克大战源代码
  19. 基于奇异值分解的图像压缩和信息隐藏
  20. 苹果手表 WatchKit 应用架构简介

热门文章

  1. 15个实用的grep示例
  2. 在ubuntu上搭建LNMP服务器
  3. malloc/free与new/delete的区别
  4. cacti安装FAQ
  5. HP前女老板Dunn和Carly的琐碎事
  6. halcon模板匹配干扰边缘消除办法(最硬核方式)
  7. 浅谈OpenCV[轉]
  8. 关于怎么怎么把 unsingned char 数据转换为 Opencv 的Mat类型,并且吧图像显示出来
  9. python字典输入学生信息_如何用Python将XML中的所有信息输入字典
  10. java10支持mybatis_写了10年的代码,我最怕写Mybatis这些配置,现在有详解了