物理内存和虚拟内存到底有什么区别?

提到内存,我们会想到经常接触的三个词:虚拟内存、物理内存、共享内存。它们分别对应top输出中的VIRT、RES、SHR三列。

1. 物理内存

系统的物理内存被划分为许多相同大小的部分,也称作内存页。内存页的大小取决于CPU的架构和操作系统的配置,一般为4KB。物理内存的使用主要分为以下几方面:

(1)内核使用

操作系统启动时,位于/boot目录下的压缩内核文件会被加载到内存中并解压。这部分内容在系统允许期间都会常驻在内存的起始位置。

(2)slab分配器

操作系统的运行还需要更多的空间来分配给管理进程、文件描述符、socket和加载的内和模块等内容。所以内核会通过slab分配器动态分配内存。

PS:slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用brk系统调用来进行分配和释放,不仅会造成大量的碎片,而且也会影响性能。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给操作系统,从而避免这些出现内存碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。可以在/proc/meminfo中查看当前slab分配器中的内存大小。

(3)进程使用

除去内核使用的部分,所有的进程都需要分配物理内存页给它们的代码、数据和堆栈。进程消耗的这些物理内存被称为“驻留内存”,RSS。

(4)页缓存page cache

除去在内核和进程使用的部分,物理内存剩下的部分被称为页缓存,page cache。因为磁盘io的速度远远低于内存的访问速度,所以为了加快访问磁盘数据的速度,页缓存尽可能的保存着从磁盘读入的数据。page cache中还有一部分称为buffer,它的作用是缓存要写入到磁盘的数据。

页缓存的大小是在一直动态变化的。当系统内存充足时,页缓存会一直增大;当系统free内存不足时,这时如果有进程申请内存,操作系统会从page cache中回收内存页进行分配,如果page cache也已不足,那么系统会将当期驻留在内存中的数据置换到事先配置在磁盘上的swap空间中,然后空出来的这部分内存就可以用来分配了。这就是swap交换。

PS:出现swap交换时,数据被置换到swap空间后(swap out),该进程使用的内存量下降,在atop等监控工具中的RGROW列为负值,但这并不表示该进程释放了内存,当它需要时,这部分数据又会被换入到内存中(swap in)。另外, swap交换往往会带来磁盘IO的大量消耗,严重影响到系统正常的磁盘io。出现大量的swap交换说明系统已经快要不行了,需要重点关注。

2. 虚拟内存

顾名思义,虚拟内存实际上并不存在,它只是存在于这套巧妙的内存管理机制中。当一个进程启动时,内核会给新的进程建立一个虚拟地址空间。这个虚拟地址空间代表了该进程可能使用到的所有内存,当然它是可以动态变化的。虚拟地址结构示意图如下,从下往上地址增大,主要包括以下几个部分:

(1)代码段:该部分只读,用于存放加载的代码。

(2)数据段:用于存放全局变量和静态变量。

(3)堆:动态内存,当malloc/free申请释放内存小于某个阈值(一般操作系统设定为128K,可以修改)时,通过brk/sbrk系统调用,控制堆顶指针向高地址偏移(malloc)或者低地址偏移(free)。

(4)文件映射区:动态内存,当malloc/free申请释放内存大于128K时,通过mmap系统调用分配一块虚拟地址空间。

(5)栈:用于存放局部变量和进程上下文。

看到这里可能会产生一个疑问:既然都有了物理内存,为什么还要有虚拟内存呢?这是因为由于成本的限制,物理内存往往无法做的很大,但是进程运行阶段所需申请的内存可能远远超过物理内存,并且系统不可能只跑一个进程,会有多个进程一起申请使用内存,如果都直接向物理内存进行申请使用肯定无法满足。通过引入虚拟内存,每个进程都有自己独立的虚拟地址空间,这个空间理论上可以无限大,因为它并不要钱。一个进程同一时刻不可能所有变量数据都会访问到,只需要在访问某部分数据时,把这一块虚拟内存映射到物理内存,其他没有实际访问过的虚拟地址空间并不会占用到物理内存,这样对物理内存的消耗就大大减少了 。

虚拟内存->物理内存的映射机制

系统内核为每个进程都维护了一份从虚拟内存到物理内存的映射表,称为页表。页表根据虚拟地址,查找出锁映射的物理页位置和数据在物理页中的偏移量,便得到了实际需要访问的物理地址。(具体的多级页表实现本文不深入探讨)

如下图所示:

这里还要提到一个概念,驻留内存,这是指虚拟内存中实际映射到物理内存的那部分,也就是进程实际占用的物理内存大小。所以判断一个进程使用的内存大小,主要是看占用的物理内存,也就是驻留内存的大小,即RSS。

3. 共享内存

进程在运行过程中,会加载许多操作系统的动态库,比如 libc.so、libld.so等。这些库对于每个进程而言都是公用的,它们在内存中实际只会加载一份,这部分称为共享内存。如上图中的A4和B3部分即为共享内存,实际都映射到同一块物理内存。

注意,进程占用的共享内存也是计算到驻留内存中的。

另外关于c++ Linux后台服务器开发的一些知识点分享:Linux,Nginx,MySQL,Redis,P2P,K8S,Docker,TCP/IP,协程,DPDK,webrtc,音视频等等视频。

喜欢的朋友可以后台私信【1】获取学习视频

linux 共享内存_什么是物理/虚拟/共享内存——Linux内存管理小结一相关推荐

  1. 删除共享内存_进程通信专题之 共享内存

    什么是共享内存呢? 共享内存是被多个进程共享一部分物理内存,共享内存是进程间共享数据最快的办法,因为一个进程向共享内存中写了数据,那么共享的这个区域的所有进程就可以立刻看到这里的数据. 共享内存有什么 ...

  2. 获取内存_如何获取一个进程所占用的内存

    推荐观看: BATJ面试官最喜欢问的:多线程.线程并发面试题详解(volatile+ThreadLocal+Sleep)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili. ...

  3. java 增加内存_如何增加java虚拟机可以使用的最大内存

    java虚拟机可使用的最大内存是有限制的,缺省值通常为64MB或128MB. 如果一个应用程序为了提高性能而把数据加载内存中而占用较大的内存,比如超过了默认的最大值128MB,需要加大java虚拟机可 ...

  4. linux工程师前景_小猿圈预测2019年Linux云计算发展前景

    近几年,新技术不断地更新,领域不断地扩大云计算.大数据.python持续发展,领跑在互联网行业的全面,造成市场需要更多这方面的人才,需求量加大,也造成了现在学习Linux的人群也相对较多,2019年l ...

  5. linux 查看日志_干货 | 名企高频考点之谈谈Linux日志查看方式都有哪些

    点击蓝字关注我哦 以下是本期干货视频视频后还附有文字版本哦 ▼<名企高频考点-谈谈Linux日志查看方式都有哪些>▼ ps:请在WiFi环境下打开,如果有钱任性请随意 0.概述 在我们面试 ...

  6. linux编程学习_您需要编程技能才能学习Linux吗?

    linux编程学习 几个月前,我参加了edX提供的Linux入门课程. 这是一门18章的课程,其中包含大量阅读材料,一些视频以及随意测试知识水平的课程. 我写了关于前六章的内容,以及该课程的工作原理, ...

  7. linux操作系统培训_免费在线技术培训丨SLE201v15 SUSE Linux Enterprise Server 15 管理课程...

    课程介绍:本课程专为那些希望从根本上了解SUSE Linux Enterprise Server(SLES)操作系统的人员而设计.学员将能够安装和配置SLES 15服务器并将其集成到现有网络中.他们将 ...

  8. 安卓一键清理内存_只需一键,即可清理iPhone内存

    昨天一期<海外 Apple ID 不用注册,也能下载>文章评论中罗优秀同学提问:能否出个清理手机内存的方法,评论中需求很多,也有很多用户在后台留言评论,请求出一期清理手机内存教程,所以今天 ...

  9. docker需要多大内存_畅玩吃鸡需要多大内存 固态硬盘作用介绍【详解】

    吃鸡需要多高配置?有玩家为吃鸡花4000+买GTX1070Ti,也有玩家嘲笑说吃鸡开最低画质看的更清晰,一张GTX 1060足矣.8G吃鸡够不够,到底有没有必要上16G内存?固态硬盘对吃鸡到底有没有用 ...

最新文章

  1. Spring、Spring Boot和TestNG测试指南 - 测试关系型数据库
  2. Windows Server 2012正式版RDS系列④
  3. 【Servlet3.0新特性】第03节_文件上传
  4. 首次公开!菜鸟弹性调度系统的架构设计
  5. 1700 Crossing River
  6. 全国计算机等级考试题库二级C操作题100套(第27套)
  7. Django 模板实现(动态)图片/头像展示到页面
  8. 作者:王倩(1983-),女,上海计算机软件技术开发中心工程师。
  9. 文件下载时,IE与FireFox对文件名编码的不同处理! Content-Disposition
  10. vs cpp代码 添加汇编_C++ 汇编代码查看
  11. 安装SQL2005出现服务器启动失败或者安装后启动服务器失败的原因及解决方法
  12. Python Scrapy中yield Request的理解
  13. 获取汉字的五笔,全拼和双拼的工具类
  14. C++:使用vector容器中的erase和swap释放内存
  15. underscoreJs中pluck函数的源码解析
  16. 计算机专业学什么代码,计算机科学与技术专业代码,本科计算机科学与技术专业代码查询...
  17. 国内免费ChatGPT
  18. DBeaver导出结果集为CSV文件,数据用引号括起来
  19. HTML——携程旅游案例
  20. 手机模拟器自带root_手机没root权限,用这款软件轻松让手机有root权限

热门文章

  1. 工程师也是主播界“扛把子”,学员抱紧大腿痴痴等候百度AI快车道下期到来...
  2. ALBERT第一作者亲自讲解:词向量、BERT、ALBERT、XLNet全面解析
  3. SIGIR 2019 开源论文 | 结合答案信息的重复问题检测方法
  4. 雇水军刷分有效吗?虚假评论的影响研究分析
  5. hadoop 启动提示输入password的问题
  6. db2 参数标识符使用无效_在Python应用程序中使用配置的最佳实践
  7. 面试让你手撕红黑树?30张图带你彻底理解红黑树~
  8. DTO数据传输对象详解
  9. Visual Studio 2019 + Visual C++——创建Visual C++ Hello World! 程序
  10. Dima and a Bad XOR