3. Linux内存管理

3. 内存管理

  • RAM 的一部分(SRAM)被静态地划分给了内核,用来存放内核代码和静态数据结构。 RAM 的其余部分(如DRAM、SDRAM、DDR)称为动态内存(dynamic memory),这不仅是运行用户进程所需的宝贵资源,也是内核所需的宝贵资源。事实上,整个系统的性能取决于如何有效地管理动态内存。

3.1 内存管理技术

  • 页表(page tables):进程在读取指令和存取数据时都要访问内存。在一个虚拟内存系统中,所有的地址都是虚拟地址而非物理地址。操作系统维护一个虚拟地址和物理地址转换的信息(页表),处理器通过这组信息将虚拟地址转换为物理地址。

  • (page):虚拟内存和物理内存被分为适当大小的块,叫做页,一般其大小为4KB。

  • 虚拟地址到物理地址的转换步骤

    1. 处理器要找到虚拟地址的页编号和页内偏移量;
    2. 处理器根据虚拟地址和物理地址的映射关系将虚拟页编号转换为物理页;
    3. 根据偏移量访问物理页的确定偏移位置。
  • 每个物理页面都有一个struct page结构,位于 include/linux/mm.h,该结构体包含了管理物理页面时的所有信息,下面给出该结构体的具体描述:

    typedef struct page {struct list_head list; 			//指向链表中的下一页struct address_space *mapping;  //用来指定我们正在映射的索引节点(inode)unsigned long index; 			//在映射表中的偏移struct page *next_hash; 		//指向页高速缓存哈希表中下一个共享的页atomic_t count; 				//引用这个页的个数unsigned long flags; 			//页面各种不同的属性struct list_head lru; 			//用在 active_list 中wait_queue_head_t wait; 		//等待这一页的页队列struct page **pprev_hash;	    //指向页高速缓存哈希表中前一个共享的页struct buffer_head * buffers; 	//把缓冲区映射到一个磁盘块void *virtual;struct zone_struct *zone; 		//页所在的内存管理区
    } mem_map_t;
    
  • 请求页面调度Demand Paging

    • 为了节省物理内存,只加载执行程序正在使用的虚拟页,这种进行访问时才加载虚拟页的技术叫做 Demand Paging。Linux 使用 demand paging 技术将可执行映像加载到进程的虚拟内存中,在执行命令时,包含命令的文件被打开,将该文件的内容映射到进程的虚拟内存中。这个过程通过修改描述进程内存映射的数据结构来实现,也叫做内存映射(memory mapping),但实际上只有映像的第一部分真正放在了物理内存中,映像的剩余部分仍然在磁盘上。
    • 当一个进程试图访问当前不在内存中的虚拟地址时,处理器无法找到引用的虚拟页对应的页表条目,也就无法将虚拟地址转换为物理地址,这时,处理器通知操作系统发生 page fault。此时区分两种情况:
      • 出错的虚拟地址无效,则意味着进程试图访问它不应该访问的虚拟地址。这种情况下,操作系统会中断它,从而保护系统中的其他进程。
      • 出错的虚拟地址有效,而只是它所在的页当前不在内存中,操作系统应该从磁盘映像中将对应的页加载到内存中。相对内存存取来讲,磁盘存取需要更长的时间,所以进程一直处于等待状态直到该页被加载到内存中。如果系统当前有其他进程可以运行,操作系统将选择其中一个运行;接着将取到的页写进一个空闲页面,并将一个有效的虚拟页条目加到进程的页表中;然后,这个等待的进程重新执行发生内存出错地方的机器指令。本次虚拟内存存取进行时,处理器能够将虚拟地址转换为物理地址,使得进程能够继续运行。
  • 页面置换技术( Swapping)

    • 如果进程需要将虚拟页放到物理内存中,而此时已经没有空闲的物理页,操作系统必须废弃物理空间中的另一页,为该页让出空间。
      • 如果物理内存中需要废弃的页来自磁盘上的映像或者数据文件,并且该页没有被写过不需要存储,则该页被废弃。如果进程又需要该页,它可以从映像或数据文件中再次加载到内存中。
      • 但如果该页已经被改变,操作系统必须保留它的内容以便以后进行访问。这种也叫做 dirty page ,当它从物理内存中废弃时,被存到一种叫做交换文件的特殊文件中。由于访问交换文件与访问处理器、物理内存的速度相比较慢,操作系统必须判断是将数据页写到磁盘上还是将它们保留在内存中以便下次访问。
    • 如果判断哪些页将被废弃或者交换的算法效率不高,则会发生颠簸(thrashing),这时页不停地被写到磁盘上,然后又被读回,操作系统频繁地处理此读写任务而无法执行实际的工作。
    • Linux 使用 LRU(Least Recently Used,最近最少使用置换算法)的页面技术公平地选择需要从系统中废弃的页面。
    • Linux 使用伙伴系统算法解决外碎片问题。把所有的空闲页框分为 11 个块链表,每个块链表分别包含 1、 2、 4、 8、 16、 32、 64、 128、 256、 512 和 1024 个连续的页框。对于 1024个页框的最大请求对应着 4MB 大小的连续 RAM 块。 每个块的第一个页框的物理地址是该块大小的整数倍。
    • 非连续内存管理,当对内存区的请求不是很频繁的时候,通过连续的线性地址访问非连续的页框,该方法可以避免外碎片,但是其带来的负面因素打乱了内核表。非连续内存区的大小必须是 4KB的倍数。非连续内存区应用的场合分别有分配数据结构给活动的交换区、分配空间给模块和分配缓冲区给某些 I/O 驱动程序。

3.2 内存区管理

  • 内存区(memory area)是指具有连续的物理地址和任意长度的内存单元序列。

  • 伙伴系统采用页框(一般取值4KB)作为基本内存区,适合于大内存的请求,但对小内存的请求容易造成内碎片。伙伴系统的调用是为了获得存放新内存区所需的额外页框,同时也为了释放不再包含内存区的页框,用一个动态链表来记录每个页框所包含的空闲内存区。

  • 为了解决内碎片的问题,将内存区大小按几何分布划分,也就是将内存区划分成 2 的幂的大小。不论请求的大小多大,总能保证内碎片小于内存区的 50%。

  • Linux内核建立了13 个按几何分布的空闲内存区链表,大小从 32B~128KB

  • 物理内存被划分为 3 个区来管理,它们是 ZONE_DMAZONE_NORMALZONE_HIGHMEM。每个区都用 struct zone_struct 结构表示, 定义于 include/linux/mmzone.h:

    typedef struct zone_struct {/* Commonly accessed fields:*/spinlock_t lock;unsigned long free_pages;unsigned long pages_min, pages_low, pages_high;int need_balance;/* free areas of different sizes */free_area_t free_area[MAX_ORDER];/* Discontig memory support fields.*/struct pglist_data *zone_pgdat;struct page *zone_mem_map;unsigned long zone_start_paddr;unsigned long zone_start_mapnr;/* rarely used fields: */char *name;unsigned long size;
    } zone_t;
    
    • lock :用来保证对该结构中其他域的串行访问。
    • free_pages :在这个区中现有空闲页的个数。
    • pages_minpages_low pages_high 是对这个区最少、次少及最多页面个数的描述。
    • need_balance:与 kswapd 合在一起使用。
    • free_area:在伙伴分配系统中的位图数组和页面链表。
    • zone_pgdat:该管理区所在的存储结点。
    • zone_mem_map:该管理区的内存映射表。
    • zone_start_paddr:该管理区的起始物理地址。
    • zone_start_mapnr:在 mem_map 中的索引(或下标)。
    • name:该管理区的名字。

3.3 内核获取内存的方式

  • 操作系统的内存管理方案优劣是决定其效率高低的重要因素,时间与空间常常作为内存管理方案优劣的衡量指标。首先,分配/释放内存是一个发生频率很高的操作,所以它要求有一定的实时性,另外,内存又是一种非常宝贵的资源,所以要尽量减少内存碎片的产生。下面介绍内核获取内存的几种方式:
    1. 伙伴算法分配大片物理内存
      • alloc_pages(gfp_mask, order):获得连续的页框,返回页描述符地址,是其他类型内存分配的基础。
      • _get_free_pages(gfp_mask, order):获得连续的页框,并返回页框对应的线性地址。线性地址与物理地址是内核直接映射方式,因此该方法不能用于高端内存(896MB以上)。
    2. slab缓冲区分配小片物理内存
      • 内核提供了后备高速缓存机制,称为“slab 分配器”。 slab 分配器实现的高速缓存具有 kmem_cache_t 类型,可通过调用 kmem_cache_create 创建:
        • kmem_cache_create:建立 slab 的高速缓冲区。
        • kmem_cache_alloc:试图从本地高速缓存区获得一个空闲的对象。
        • kmalloc(gfp_mask, size):获得连续的以字节为单位的物理内存,返回线性地址。
    3. 非连续内存区分配
      • vmalloc(size):分配非连续内存区,其线性地址连续,物理地址不连续,减少了外碎片,但是其性能低,因为要打乱内核页表。通常只是分配大内存,例如为活动的交互区分配数据结构、加载内核模块时分配空间、为 I/O 驱动程序分配缓冲区。
    4. 高端内存映射
      • kmap(struct page * page):用于获得高端内存永久内核映射的线性地址 ;
      • kmap_atomic(struct page * page, enum km_type type):用于获得高端内存临时内核映射的线性地址
    5. 固定线性地址映射
      • set_fixmap(idx, phys):把一个物理地址映射到一个固定的线性地址上。
      • set_fixmap_nocache(idx, phys):把一个物理地址映射到一个固定的线性地址上,但禁用该页高速缓存

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

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

相关文章

Java+SpringBoot+Vue+MySQL:美食推荐系统的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

学习JAVA的第七天(基础)

目录 static 静态变量 静态方法 工具类: static的注意事项 继承 继承的好处 继承的特点 方法的重写 书写格式 override重写注解 方法重写的要求 this关键字 super关键字 static static表示静态,是Java中的一个修饰符,可以修饰成…

基于STM32的蓝牙遥控小车:手机APP控制小车运动

这里写目录标题 一、智能双轮小车蓝牙APP控制前后左右调速运动功能描述原理图设计PCB设计源码设计 二、更多功能小车网友推荐后开发... 一、智能双轮小车蓝牙APP控制前后左右调速运动 功能描述 1、小车可以前后左右运动 2、可以调节小车的速度 3、使用两个电机驱动两个轮子&a…

Go语言必知必会100问题-06 生产者端接口

生产者端接口 Go语言必知必会100问题-05 接口污染中介绍了程序中使用接口是有价值的。在编码的时候,接口应该放在哪里呢?这是Go开发人员经常有误解的一个问题,本文将深入分析该问题。 在深入探讨问题之前,先对提及的术语做一个定…

MySQL(2/3)

select和别名的使用 主要是用以查询数据 语法:select 字段 from 库名 -- *代表全部字段 select * from student; -- 可以查询多个字段,并使用as起别名,as可以省略 select id as bbb ,name as hhh from student; -- 可以使用函数concat(a,b…

新版Java面试专题视频教程——虚拟机篇②

新版Java面试专题视频教程——虚拟机篇② 3 垃圾收回3.1 简述Java垃圾回收机制?(GC是什么?为什么要GC)3.2 对象什么时候可以被垃圾器回收3.2.1 引用计数法3.2.2 可达性分析算法 3.3 JVM 垃圾回收算法有哪些?——4种3.3…

Python实现DAS单点登录

❇️ 流程 进入登录页面 (DAS验证的登录页面) 获取验证码图像,百度OCR识别 登录 🏞️ 环境 Windows 11 Python 3.12 PyCharm 2023 🧵 准备工作 安装必要依赖库 bs4 Jupyter 推荐安装 Jupyter(Anaco…

数学建模【相关性模型】

一、相关性模型简介 相关性模型并不是指一个具体的模型,而是一类模型,这一类模型用来判断变量之间是否具有相关性。一般来说,分析两个变量之间是否具有相关性,我们根据数据服从的分布和数据所具有的特点选择使用pearson&#xff…

Linux系统——Nginx小总结

目录 一、影响用户体验的因素 二、网络连接——Apache/Nginx服务请求过程 三、I/O模型——Input/Output模型 1.同步/异步 2.阻塞/非阻塞 3.同步异步/阻塞非阻塞组合 四、Nginx用法 一、影响用户体验的因素 客户端硬件配置客户端网络速率客户端与服务端距离服务端网络速…

容器库(12)-std::unordered_multiset

unordered_multiset是以key为元素无序的关联容器,搜索、移除和插入操作是平均常数的时间复杂度。unordered_multiset在内部没有按任何顺序排列,而是放在桶当中的,放进哪个桶是通过计算key的hash值来决定的。和unordered_set不同的是&#xff…

【JS】事件绑定方法自带一个形参e“function(e)”,what is e?

在学习js的时候 我跳过了一部分章节的内容,导致现在学习react的时候很多内容都不知所措,因为这些教程都是建立在它认为你js所有内容都掌握的前提下,当然这是我自身的原因。需要反省。 下面是正题: 我们知道js有很多事件&#…

学习 Python operator 模块的 itemgetter

学习 Python operator 模块的 itemgetter 0. 引言1. itemgetter函数说明1-1. 示例代码1-2. 多级排序 0. 引言 operator模块提供了一系列对操作符的函数化接口,例如:加法、乘法、比较操作等。 itemgetter函数是operator模块中的一个功能,它用…

【一】【SQL】表的增删查改(部分)

表之“增”操作 建表的操作 mysql> create table students(-> id int unsigned primary key auto_increment,-> sn int unsigned unique key,-> name varchar(20) not null,-> qq varchar(32) unique key-> ); Query OK, 0 rows affected (0.03 sec)mysql&g…

v-rep--addon--附加组件

附加组件汉化文档 官网 什么是addon 就是一个lua语言文件; 用户通过编写的lua文件来增加coppeliasim的功能。 addon的作用 通过用户编写的lua语言实现添加coppliasim功能。

Day01:Web应用架构搭建站库分离路由访问配置受限DNS解析

目录 常规的Web应用搭建 三种常规网站搭建模式 程序源码 中间件配置 数据库类型 文件访问路径 总结 章节知识点: 应用架构:Web/APP/云应用/三方服务/负载均衡等 安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令:文件…

Pytorch添加自定义算子之(1)-安装配置Eigen库

一、安装对应的ubuntu环境 推荐使用Docker FROM nvcr.io/nvidia/pytorch:23.01-py3 RUN pip install tensorboardX RUN pip install pyyaml RUN pip install yacs RUN pip install termcolor RUN pip install opencv-python RUN pip install timm0.6.12 WORKDIR /app COPY . …

Python入门必学:print函数--从基础语法到高级用法

Python入门必学:print函数–从基础语法到高级用法 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 👈 希望得到您…

2024 春招市场行情报告:鸿蒙人才遭“爆抢”

前言 2024年可以说是布道鸿蒙开发行业的最佳时机,华为在千帆启航仪式会中发布会中表示,已有200家头部企业加入原生开发当中,并且一直有高薪抢人的局面,这一信息已经引起业界很大关注。 因此有很多公司开始准备要招聘鸿蒙工程师&…

机器学习YOLO操作全流程​​编

YOLO介绍 Ultralytics YOLOv8,是最新的著名实时目标检测和图像分割模型。它基于深度学习和计算机视觉的最新进展,提供了无与伦比的速度和精度性能。由于其精简的设计,适用于各种应用,并且可以轻松适配不同的硬件平台,从边缘设备到云端API。 探索 YOLOv8 文档,这是一个全…

R语言【BIEN】——BIEN_occurrence_genus():从BIEN数据库下载特定属的观察记录。

Package BIEN version 1.2.6 Description BIEN_occurrence_genus() 从BIEN数据库下载特定属的观察记录。 Usage BIEN_occurrence_genus(genus,cultivated FALSE,new.world NULL,all.taxonomy FALSE,native.status FALSE,natives.only TRUE,observation.type FALSE,poli…