Linux最深刻理解页表于物理内存

目录

物理内存管理

页表设计


物理内存管理

如果磁盘上的内容加载到物理内存上,每次io都会按照4kb的方式进行加载(可能不同版本系统有些区别)。所以我们的物理内存上的内容也是4个字节进行管理的。
而每个页框都需要我们进行管理。所以自然物理内存就会对页框进行先描述,再组织。物理内存就有struct page[]这个数组来管理所有的页框了。


struct page {unsigned long flags;union {struct {/* 换出⻚列表,例如由zone->lru_lock保护的active_list */struct list_head lru;/* 如果最低为为0,则指向inode* address_space,或为NULL* 如果⻚映射为匿名内存,最低为置位* ⽽且该指针指向anon_vma对象*/struct address_space* mapping;/* 在映射内的偏移量 */pgoff_t index;/** 由映射私有,不透明数据* 如果设置了PagePrivate,通常⽤于buffer_heads* 如果设置了PageSwapCache,则⽤于swp_entry_t* 如果设置了PG_buddy,则⽤于表⽰伙伴系统中的阶*/unsigned long private;};struct {/* slab, slob and slub */union {struct list_head slab_list;/* uses lru */struct {/* Partial pages */struct page* next;
#ifdef CONFIG_64BITint pages;/* Nr of pages left */int pobjects;/* Approximate count */
#elseshort int pages;short int pobjects;
#endif};};struct kmem_cache* slab_cache;/* not slob *//* Double-word boundary */void* freelist;/* first free object */union {void* s_mem;/* slab: first object */unsigned long counters;/* SLUB */struct {/* SLUB */unsigned inuse : 16;/* ⽤于SLUB分配器:对象的数⽬ */unsigned objects : 15;unsigned frozen : 1;};};};...};union {/* 内存管理⼦系统中映射的⻚表项计数,⽤于表⽰⻚是否已经映射,还⽤于限制逆向映射搜索*/atomic_t _mapcount;unsigned int page_type;unsigned int active;/* SLAB */int units;/* SLOB */};...
#if defined(WANT_PAGE_VIRTUAL)/* 内核虚拟地址(如果没有映射则为NULL,即⾼端内存) */void* virtual;
#endif/* WANT_PAGE_VIRTUAL */...
}

1. flags :⽤来存放⻚的状态。这些状态包括⻚是不是脏的,是不是被锁定在内存中等。flag的
每⼀位单独表⽰⼀种状态,所以它⾄少可以同时表⽰出32种不同的状态。这些标志定义在
<linux/page-flags.h>中。其中⼀些⽐特位⾮常重要,如PG_locked⽤于指定⻚是否锁定,PG_uptodate⽤于表⽰⻚的数据已经从块设备读取并且没有出现错误。
2. _mapcount :表⽰在⻚表中有多少项指向该⻚,也就是这⼀⻚被引⽤了多少次。当计数值变
为-1时,就说明当前内核并没有引⽤这⼀⻚,于是在新的分配中就可以使⽤它。
3. virtual :是⻚的虚拟地址。通常情况下,它就是⻚在虚拟内存中的地址。有些内存(即所谓
的⾼端内存)并不永久地映射到内核地址空间上。在这种情况下,这个域的值为NULL,需要的
时候,必须动态地映射这些页。

以4GB大小的物理内存,一个页框4kb举例。
所以我们就有4GB/4KB=1,048,576个页框也就有1,048,576个struct page;
struct page按40bity大小算,所以页框也就占40MB。对于4GB,40MB已经很小了。

如何通过页框访问到struct page
从磁盘加载到内存其实连续的,比如他要加载3个页框,那3个页框里面的东西只能是一个文件里的东西,即使第3个页框没有用完,下一个文件也会从第4个页框开始加载。4kb里的内存,都是以每个字节进行编制。所以要访问一个页框的struct page,就可以通过物理地址/4kb,就得到struct page[N]的下标了。

页表设计

再来思考一个问题
操作系统可以想为用户提供连续的地址,但是在物理地址上他并不会给我开辟连续的地址。

如果是这样我们如果保证他们要连续呢?
所以就有了我们的页表
我们页表就可以保证他们连续,在进程加载时就要对虚拟地址与物理地址进行映射?那他们时如何映射的呢?
下面以4GB大小的物理内存,一个页框4kb举例。
我们的页表并会像这样左边是虚拟地址,右边是物理地址。应为这样太占内存了!4GB的物理地址要做映射,页表最大花销就是16GB。


而有人想出了下边这个做法,非常的厉害。
以一个4bity的地址举例


我们的页目录表对一个前十个bit(一级页号)位进行解析,在去哪个页表,通过第11位到20bit位(二级页号)寻找到页表下的地址,最后的12个比特位刚好4096,最后指向每个4kb内的地址。
这里算一算页表能表示的地址有:1024*1024*4098=4294967296
再看4GB以字节序编址就有:4*1024*1024*1024=4294967296
这样不就是4GB大小的地址空间了吗。
这样的页表就只需花费1024*1024*4=4MB大小的页表就能映射4GB大小的物理内存!确实非常伟大设计!
所以我们所说页表,其实是由页表目录和页表共同组成的。上面的那种说法只是说明物理内存与虚拟内存进行映射而已

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

一键高效管理:苹果手机如何一键删除照片

在我们的日常生活中&#xff0c;苹果手机不仅是沟通的工具&#xff0c;更是捕捉和保存生活瞬间的重要设备。随着时间的推移&#xff0c;数以千计的照片积累在设备中&#xff0c;这不仅占用了大量的存储空间&#xff0c;也可能影响设备的性能。本文将详细介绍苹果手机如何一键删…

C++:类和对象(二)

C&#xff1a;类和对象&#xff08;二&#xff09; 类的默认成员函数构造函数析构函数拷贝构造函数 类的默认成员函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。⼀个类&#xff0c;我们不写的情况下编译器会默认生成以下6个…

机器学习(基础2)

特征工程 特征工程:就是对特征进行相关的处理 一般使用pandas来进行数据清洗和数据处理、使用sklearn来进行特征工程 特征工程是将任意数据(如文本或图像)转换为可用于机器学习的数字特征,比如:字典特征提取(特征离散化)、文本特征提取、图像特征提取。 特征工程API 实例化…

ts中的元组概念解释(tuple)

用于定义数组每个元素的类型 元组 (Tuple) 是⼀种特殊的数组类型&#xff0c;可以存储固定数量的元素&#xff0c;并且每个元素的类型是已知的且可以不同。元组⽤于精确描述⼀组值的类型&#xff0c; ? 表示可选元素 1&#xff0c;正常写法 let list1 :[string,number] li…

Rust,删除cargo安装的可执行文件

列出安装的文件列表 cargo install --list 删除 rm /Users/ry/.cargo/bin/fancy

数据库中生成主键的方式及其优缺点

数据库中生成主键的方式及其优缺点 一、自动增长(AUTO_INCREMENT) 使用方法&#xff1a;设置auto_increment 实现数据表自增&#xff1b; 优点&#xff1a; 简单易用&#xff1a;自增主键是一种简单的方式&#xff0c;只需在数据库表中设置自增属性即可&#xff0c;无需在代…

linux进程管理

进程和线程的关系 以下介绍为linux环境 进程是操作系统中一个运行中的程序&#xff0c;是资源分配和调度的基本单位。每个进程有自己独立的内存空间、文件描述符、堆栈等系统资源 线程&#xff08;Thread&#xff09; 是 CPU 调度的最小单位&#xff0c;是进程中的一个执行流…

unity基础,点乘叉乘。

简单记录下点乘叉乘&#xff0c;要不每次用完就忘&#xff0c;忘了又查。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class TestCrossDot : MonoBehaviour {/// <summary>/// 原点/// </summary>public Transform t…

Vue2+ElementUI:用计算属性实现搜索框功能

前言&#xff1a; 本文代码使用vue2element UI。 输入框搜索的功能&#xff0c;可以在前端通过计算属性过滤实现&#xff0c;也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤&#xff0c;后附完整代码&#xff0c;代码中提供的是死数据&#xff0c;可…

JAVA学习日记(十二)查找算法

一、基本查找、二分查找 略 二、分块查找 将数组分块&#xff0c;每一个块中最大值小于后一个块中的最小值&#xff1a;块内无序&#xff0c;块间有序。 块&#xff1a;创建一个块类 按照规则划分好块之后&#xff0c;对要查询的值设计方法进行查询。 import java.util.…

多线程小知识

一. CAS CAS (Compare and Swap, 比较并交换) 是一种无锁编程技术, 用于实现多线程环境下对共享资源的线程安全访问. CAS 的核心思想是: 只有当内存中的值与预期值相匹配时, 才会将内存中的值更新为新值. 寄存器1中存放原值, 寄存器2中存放新值. 现在要将内存中的原值更新为新…

C++基础(12.红黑树实现)

目录 红黑树的概念&#xff1a; 红黑树规则&#xff1a; 红黑树如何确保最长路径不超过最短路径的2倍的&#xff1f; 红黑树的效率&#xff1a; 红黑树的插入: 红黑树树插入⼀个值的大概过程: 情况1&#xff1a;变色 情况2&#xff1a;单旋变色&#xff1a; 情况3&…

代码随想录算法训练营第二十天|39. 组合总和、40.组合总和II、131.分割回文串

39. 组合总和 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;带你学透回溯算法-组合总和&#xff08;对应「leetcode」力扣题目&#xff1a;39.组合总和&#xff09;| 回溯法精讲&#xff01;_哔哩哔哩…

机器学习基础02_特征工程

目录 一、概念 二、API 三、DictVectorize字典列表特征提取 四、CountVectorize文本特征提取 五、TF-IDF文本1特征词的重要程度特征提取 六、无量纲化预处理 1、MinMaxScaler 归一化 2、StandardScaler 标准化 七、特征降维 1、特征选择 VarianceThreshold 底方差…

得物App入选诚信案例,10万正品样品库夯实高品质消费

近日&#xff0c;以“加强企业诚信建设 赋能经济社会发展”为主题的“2024年全国企业诚信建设大会”在烟台市召开。此次大会由中国企业联合会、中国企业家协会主办&#xff0c;山东省企业联合会、山东省企业家协会、烟台市企业联合会、烟台大学承办。大会期间&#xff0c;得物A…

036 RabbitMQ消息确认 死信队列 延时队列

文章目录 生产者确认模式application.propertiesMessageController.javaMessageConfirmRallback.java 生产者回退模式application.propertiesMessageConfirmRallback.javaMessageController.java 消费者手动确认application.propertiesConsumerAckQueueListener.java 死信队列延…

docker desktop运行rabittmq容器,控制台无法访问

docker desktop运行rabittmq容器&#xff0c;控制台无法访问 启动过程&#xff1a;…此处缺略&#xff0c;网上一大堆 原因 原因是在Docker上运行的RabbitMQ&#xff0c;默认情况下是没有启用管理插件和管理页面的 解决办法 使用命令 docker exec -it 容器id /bin/bash 进…

Tailwind 安装使用

Tailwind 安装使用 前言 CSS原子化——本文将详细介绍如何在Vue Vite npm环境下安装、配置并使用Tailwind CSS&#xff01; 文章目录 Tailwind 安装使用前言一、Tailwind 在 Vue Vite 项目中的安装1. 创建Vue项目2. 安装Tailwind CSS3. 初始化Tailwind配置4. 修改文件 tai…

centos7安装playwright踩坑记录

Python版本安装 Installation | Playwright Python 1. 安装pytest-playwright pip3 install pytest-playwright报错&#xff1a;提示找不到pytest-playwright 原因&#xff1a;服务器Python版本3.6.8太低&#xff0c;貌似pytest-playwright最低支持3.7 解决方法&#xff1…

函数(C语言)

1&#xff1a;函数的概念 函数的概念我们在初中的时候就已经听过了。 在C语言中也引入了函数&#xff0c;也可以叫子程序 C语言中的函数就是一个完成某项特定的任务的一小段代码 这段代码是有特殊的写法和调用方法的。其实C语言的程序也是由无数个小的函数组成的。 也就是&…