【Linux】第二十七站:内存管理与文件页缓冲区

文章目录

  • 一、物理内存和磁盘交换数据的最小单位
  • 二、操作系统如何管理内存
  • 三、文件的页缓冲区
  • 四、基数树or基数(字典树)
  • 五、总结

一、物理内存和磁盘交换数据的最小单位

image-20231204201348600

我们知道系统当中除了进程管理、文件管理以外,还有内存管理

内存的本质就是对数据的一种临时存取,所以我们可以把内存看作一个非常大的缓冲区就可以了。

当内存需要数据的时候,可以直接从磁盘中读取,不需要的时候可以直接释放或者与磁盘进行交换

image-20231204202436014

为了方便物理内存与磁盘进行交互,我们会将物理内存看作一个一个的小格子,内存也是一种线性的。这个一个个的小单位是4KB

image-20231204202810807

像我们平时形成的可执行程序也是一个一个的以4KB为单位的小的数据段。

也就是说,如果一个可执行程序是4M,那么其实这个可执行程序也是4KB,4KB进行划分的。这是因为文件系统中数据块的大小就是4KB。

所以可执行程序在文件系统中天然就是每读一个块就是4KB

image-20231204203027361

而我们就将物理内存的这一个个4KB就叫做页框,将磁盘当中的这一个个4KB叫做页帧

image-20231204203413702

那么为什么必须是4KB,可以是1KB,2KB吗?

当然是可以的,不过这样我们需要修改操作系统的底层源代码。最终重新编译操作系统

而我们为什么要选择4KB呢,我们的文件压根可能就没有4KB。可能就是1KB,那么那3KB就浪费了。即便某个文件只有一个比特位,我们也不能只拿这1个比特位,必须将这4KB全部加载进来。

我们知道磁盘本身就是一个机械设备,注定了它IO时候访问的周期比较长,即比较慢,一次4KB很显然要比一次1KB效率要更高一些。(因为只需要磁头定位一次即可。比要定位四次快得多)

其次就是计算机中存在着局部性原理:在访问某些代码和数据时候,它附近的代码和数据也有很大概率被访问。而且因为机械运动才是慢的主要矛盾,有可能我们的文件只有100字节,但是我们也要读取4KB,这两个的效率其实差不多。而且100字节可能更加分散,需要更加精细

所以就有了基于局部性原理的预加载机制

  1. 它可以减少IO的次数,从而对系统整体进行提速 ----硬件

  2. 基于局部性原理,有了预加载机制 ----软件

注意这里的4KB是物理内存和磁盘交换数据的单位

二、操作系统如何管理内存

在操作系统层面上,要管理内存,肯定会用到虚拟地址。

而操作系统管理内存,也肯定是能看到内存的物理地址的。

那么操作系统如何管理内存呢??

先描述后组织

所以在操作系统里面肯定有一个东西

struct page
{//page页必要的属性信息。
};

​ 像我们的系统如果有4GB的内存的话,那么最终会存在1024*1024*\1024*4 /4/1024,即约100万多个页。

然后我们在操作系统内核里面直接定义

struct page mem_array[1048579]

所以我们发现对内存的管理变为了对数组的管理。

即先描述后组织

而我们知道数组是天然有下标的,所以我们就天然的有了页号的概念

所以以后当有了一个地址以后,我们就可以知道它是在哪一个页号上的

因为4KB,需要用12位

所以我们只需要将这个低12位全部清零即可

比如0x11223344,我们直接让他按位与上0xFFFFF000

所以它最终的页号就是0x11223000

所以我们就直接用这个页号就找到了对应的属性

所以,我们要访问一个内存,我们只需要先直接找到这个4KB对应的Page,就能在系统中找到对应的物理页框

在我们系统中,所有申请内存的动作,都是在访问内存Page数组

而且这个Page结构体不会很大,因为会有一个Page类型的数组,它最终也是要在内存中存放着的,所以它不能太大,所以这也再次说明了前面的页框大小不能太小,因为它越小,这个数组就越大,占据的内存空间越大。

如下所示,它的page里面都是一些union,这个flags代表它的使用状态。(每一个比特位都有它的含义,比如当我要使用这个页框的时候,我们只需要判断其中的一个标志位是否为0,如果为0那么改为1,这个内存就被使用了)。下面的这个count代表的就是引用计数。用来判断该内存被多少人使用。

image-20231204212533812

同时在这个Page中还有一个lru,它是最近最少使用。也就是说操作系统会将最近最少使用的东西拿出来给刷新出去。

image-20231204213014901

三、文件的页缓冲区

如下图所示

在我们开机的时候,不仅仅是为我们创建了进程了,内存管理做好了等等。

还会将我们文件系统相关的数据都已经预加载到内存了,尤其是Super Block等这些文件系统相关的信息

image-20231205154712705

我们可能会说,那在操作系统上存在着很多分区,这也无所谓,因为可以用链表将他们组织起来

image-20231205155052716


如下是一个操作系统,里面有进程、files_struct等内核数据结构

image-20231205155603366

所以最终操作系统上层用的都是fd文件描述符

当我们在打开文件的时候,我们必须知道这个文件的路径+文件名,然后我们就能读取当前目录的数据块,从而找到文件的inode

因为这些inode Bitmap,Block Bitmap已经被提前加载到内存中了。然后我们确认这个inode是否存在,如果存在,直接将这个inode给加载进来,最后也就能读取到对应的数据块了。

以上都是一个文件被加载到内存当中的过程。

而现在我们关心的是这两件东西:文件的属性+文件的内容

所以我们需要做的就是,文件的属性如何被拿到。

我们知道文件的属性都在inode里面,struct file里面也有文件的属性,不过只有少量的属性。

所以我们会创建一个内核数据结构,struct inode,然后直接将磁盘中的inode里面的内容填写到这个内核数据结构中。而这个struct file是可以找到struct inode的

image-20231205161404122

可是我们之前说过,我们在上层调用fprintf以后,就会通过这个fd,往对应进程中找到对应的文件描述符,从而去找到struct file结构体。那么在这里如何将数据写到磁盘中呢?

我们现在只能去找到文件的属性

其实在struct file里面还存在一个结构叫做address_space。

image-20231205162743341

而radix_tree_root它是一颗多叉树

它结点里面是这样的结构

image-20231205172031647

如下图所示,它的每一个叶子结点都指向一个struct page对象,而这样的每一个struct page对象都对应着4KB的内存大小

image-20231205172537588

所以说当我们将数据拷贝到struct file以后,就会找到address_space,然后一路找到这棵树的叶子节点中,最终通过这个叶子节点的struct page去管理对应的内存

而上面这个就是文件的页缓冲区

四、基数树or基数(字典树)

在Linux中,我们的每一个进程,打开的每一个文件都要有自己的inode属性和自己的文件页缓冲区

什么是字典树呢?

类似于下面的26叉树每个结点可以指向26个字母

image-20231205174034476

我们可以用下面这个3个字母简单的来代替

image-20231205174230362

当我们要查找某个对象的时候,我们可以用bbb来作为key值,从而找到某个对象

image-20231205174428285

文件的内容按照4kb是有偏移量的

比如一个10MB的文件,它占据的内存就是10*1024*1024

而文件的内容是按照4KB一块一块的进行存储着的

image-20231205175531801

而这刚好就是2560块

所以我们就可以给他进行编号[1,2560]

而每一块乘以4KB就是他们的相对于原始数据的偏移量

所以前面的这一批数字[1,2560]它刚好每一个编号都是一个int类型的

而int类型是占据32位的

比如有一个数据是0xFF FF FF FF

这个整数我们可以将第一个数字看作一个b,第二个数字看作一个c,第三个数字看作一个a

如果我们可以像前面那样构建出一颗字典树

我们就可以利用这个文件的内容所在的区域

就可以利用字典树,找到对应的page的映射关系。


所以当我们进行读写文件的时候,从开头读,每一个读写都有偏移量。

根据这个偏移量,就可以将这个偏移量转化为树中的某一个page

这样我们就可以根据它的page偏移量,就确定先刷新哪一个page,后刷新哪一个page,就可以让文件有序的进行刷新了

最终我们的数据就成功的写入到了内存中

当我们将数据写入到了内存中以后,后序数据从内存如何写入到磁盘,就不是操作系统需要关心的事情了,这就导致了当我们突然断电以后,内存里面的数据都无法保存起来

上面的这个从内存刷新到磁盘当中的过程就是驱动层的事情了, 需要IO子系统来进行完成

五、总结

总之上面的过程其实就是下面的这张图

也就是说,操作系统里面也有一个文件缓冲区,最后它会被刷新到磁盘上去

image-20231205183319960

上面的过程,我们就把打开文件和文件系统的文件 产生关联了!

我们也可以发现,这里一共要经历三次拷贝,第一次将数据写入到C语言缓冲区中,第二次将数据从C语言缓冲区写入到文件缓冲区中,第三次是写在磁盘当中去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/212363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

思科最新版Cisco Packet Tracer 8.2.1安装

思科最新版Cisco Packet Tracer 8.2.1安装 一. 注册并登录CISCO账号二. 下载 Cisco Packet Tracer 8.2.1三. 安装四. 汉化五. cisco packet tracer教学文档六. 正常使用图 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新…

[香橙派]orange pi zero 3 烧录Ubuntu系统镜像——无需HDMI数据线安装

一、前言 本文我们将介绍如何使用orange pi zero 3 安装Ubuntu系统,本文相关步骤均参考自开发手册。 二、实施准备 根据开发手册中所提到的,我们应该拥有如下配件: 1.orange pi zero 3 开发板 2.TF 卡——最小 8GB 容量的 class10 级或以上的高速闪迪卡。…

鸿蒙OS应用开发之语句

在程序开发中,已经有上面的运算符和数据类型了,可以满足了大部的需求,但是这些程序还是比较简单的计算和逻辑运算,如果需要复杂的计算和逻辑处理,就需要采用复杂逻辑程序块来处理了,也就是复杂条件语句才能…

模型 心流

本系列文章 主要是 分享模型,涉及各个领域,重在提升认知。完全投入其中。 1 心流的应用 1.1 优秀运动员的心流体验 迈克尔乔丹(Michael Jordan):篮球之神乔丹在比赛中经常进入心流状态,他曾表示&#xff…

DIY手工艺作坊网站建设的作用如何

我国文化悠久流长,很多手工艺品制作技术放在如今依然有很高的需求度,加之现代新增的技艺,样式多且艺术性强,比如常见的陶器手工制作技术,当然还有更多。 而对相关作坊来说,除了艺术传承外,还需…

接触刚性环境任务下的机器人力控(阻抗)性能测试

内涵 接触刚性环境任务下的机器人力控(阻抗)性能测试旨在评估机器人在与刚性物体交互时的性能表现。这种测试通过调整机器人的控制参数,如期望刚度和期望阻尼等,并分析记录的数据,旨在确保机器人能够在执行任务时保持…

短剧分销小程序/APP开发:开启短剧收益时代

今年,短剧火爆出圈,市场规模将达至200亿元至300亿元。国内全全平台付费短剧日充值金额为6000万元,短剧作为一种“快餐式”文化迅速爆火。 短剧契合了观众娱乐时间碎片化的发展趋势,相比于传统的电视剧,短剧节奏快、剧…

MongoDB的连接数据库,创建、删除数据库,创建、删除集合命令

本文主要介绍MongoDB的连接数据库,创建、删除数据库,创建、删除集合命令。 目录 MongoDB连接数据库连接到本地 MongoDB 实例连接到远程 MongoDB 实例 MongoDB创建和删除数据库MongoDB创建和删除集合创建集合删除集合 MongoDB连接数据库 连接 MongoDB 数…

P1317 低洼地题解

题目 一组数,分别表示地平线的高度变化。高度值为整数,相邻高度用直线连接。找出并统计有多少个可能积水的低洼地? 如图:地高变化为 [0,1,0,2,1,2,0,0,2,0]。 输入输出格式 输入格式 两行,第一行n, 表示有n个数。第…

openGauss学习笔记-151 openGauss 数据库运维-备份与恢复-物理备份与恢复之gs_basebackup

文章目录 openGauss学习笔记-151 openGauss 数据库运维-备份与恢复-物理备份与恢复之gs_basebackup151.1 背景信息151.2 前提条件151.3 语法151.4 示例151.5 从备份文件恢复数据 openGauss学习笔记-151 openGauss 数据库运维-备份与恢复-物理备份与恢复之gs_basebackup 151.1 …

基于java swing 药品销售管理系统

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

短视频账号剪辑矩阵+无人直播系统源头开发

抖去推爆款视频生成器,通过短视频矩阵、无人直播,文案引流等,打造实体商家员工矩阵、用户矩阵、直播矩阵,辅助商家品牌曝光,团购转化等多功能赋能商家拓客引流。 短视频矩阵通俗来讲就是批量剪辑视频和批量发布视频&am…

Multisim电路仿真软件使用教程

安装直接参考这篇文章:Multisim 14.0安装教程 软件管家公众号里有很多软件,需要的可以去找下然后安装,这里用的是14.0版本。 这里有个大神的详细教程,可以参考: Multisim软件使用详细入门教程(图文全解&…

Python房价分析(二)随机森林分类模型

目录 1 数据预处理 1.1 房价数据介绍 1.2 数据预处理 1.2.1 缺失值处理 1.2.2异常值处理 1.2.3 数据归一化 1.2.4 分类特征编码 2 随机森林模型 2.1 模型概述 2.2 建模步骤 2.3 参数搜索过程 3模型评估 3.1 模型评估结果 3.2 混淆矩阵 3.3 绘制房价类别三分类的…

面试官:性能测试瓶颈调优你是真的会吗?

引言:性能瓶颈调优 在实际的性能测试中,会遇到各种各样的问题,比如 TPS 压不上去等,导致这种现象的原因有很多,测试人员应配合开发人员进行分析,尽快找出瓶颈所在。 理想的性能测试指标结果可能不是很高&…

Latex公式中矩阵的方括号和圆括号表示方法

一、背景 在使用Latex写论文时,不可避免的涉及到矩阵公式。有的期刊要求矩阵用方括号,有的期刊要求矩阵用圆括号。因此,特记录一下Latex源码在两种表示方法上的区别,以及数组和方程组的扩展。 二、矩阵的方括号表示 首先所有的…

OpenGLES:glReadPixels()获取相机GLSurfaceView预览数据并保存

Android现行的Camera API2机制可以通过onImageAvailable(ImageReader reader)回调从底层获取到Jpeg、Yuv和Raw三种格式的Image,然后通过保存Image实现拍照功能,但是却并没有Api能直接在上层直接拿到实时预览的数据。 Android Camera预览的实现是上层下发…

Java学习笔记——instanceof关键字

instanceof关键字: 作用:保证对象向下转型的安全性在对象向下转型前判断某一对象实例是否属于某个类 判断时,如果对象是null,则 instanceof 判断结果为 false

Tr0ll

信息收集 探测主机存活信息: nmap -sn --min-rate 10000 192.168.182.0/24Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-14 15:45 CST Nmap scan report for 192.168.182.1 Host is up (0.00026s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap…

Linux环境下socket本地通信

最近项目有用到了socket本地通信,故复习一下。之前都是基于本地虚拟机的ip地址通信的,现在项目,Linux单板上面有2个进程需要通信,故用到了本地socket通信,主要其实就是用了sockfd,文件描述符,也叫句柄。 服…