Linux内核学习(八)—— 内存管理(基于Linux 2.6内核)

目录

一、页(page)

二、区(zone)

三、页操作

四、kmalloc()

五、vmalloc() 

六、slab 分配器

七、在栈上的静态分配


一、页(page)

内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻        址单位通常为字或字节,但是,内存管理单元(MMU,管理内存并把虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。MMU 以页为单位来管理系统中的页表。从虚拟内存的角度来看,页就是最小单位。

大多数 32 位体系结构支持 4KB 的页,而 64 位体系结构一般会支持 8KB 的页。

内核用 struct page 结构表示系统中的每个物理页,位于 <linux/mm_types.h> 中,定义如下:

  • flags 用来存放页的状态,比如页是否是脏的(内存数据页和磁盘数据页内容不一致),是不是被锁定在内存中等。flags 每一位都可以表示一种状态,状态标志定义在 <linux/page-flags.h> 中。
  • _count 存放页的引用计数,也就是这一页被引用了多少次。当计数值为 -1 时,就说明当前内核并没有引用这一页,在新的分配中就可以使用它。内核代码不应该直接查看这个参数,而是调用 page_count() 函数进行检查,传入 page 结构,返回 0 表示空闲。
  • virtual 存放页的虚拟地址。 通常情况下,它就是页在虚拟内存中的地址。但有些内存(高端内存)并不永久地映射到内核地址空间上。这种情况下 virtual 的值为 NULL。

page 结构与物理页相关,而并非与虚拟页相关。内核用这一结构来管理系统中所有的页,因为内核需要知道一个页是否空闲。一个页的拥有者可能是用户空间进程、动态分配的内核数据、静态内核代码或页高速缓存。

二、区(zone)

由于硬件的限制,有些页位于内存中的特定的物理地址上,所以不能将其用于一些特定的任务,于是内核把页划分为不同的区(zone) ,由此对具有相似特性的页进行分组。Linux 必须处理如下两种由于硬件存在缺陷而引起的内存寻址问题:

  • 一些硬件只能用某些特定的内存地址来执行 DMA(直接内存访问)。
  • 一些体系结构的内存的物理地址寻址范围比虚拟寻址范围大得多,这样就有一些内存不能永久地映射到内核空间上。

因此,Linux 划分了四种区:

  • ZONE_DMA:这个区包含的页能用来执行 DMA 操作。
  • ZONE_DMA32:这个区包含的页能用来执行 DMA 操作,但这些页面只能被 32 位设备访问。
  • ZONE_NORMAL:这个区包含的都是能正常映射的页。
  • ZONE_HIGHEM:这个区包含高端内存(high memory),其中的页并不能永久地映射到内核地址空间。系统内其余内存就是所谓的低端内存(low memory)。

Linux 把系统的页划分为分区,形成不同的内存池,这样就可以根据用途进行分配了。区是内存为了管理页而采取的一种逻辑上的分组。

三、页操作

内核提供了几种请求页的接口,所有接口都以页为单位分配内存,定义于 <linux/gfp.h> 中,最核心的是:

struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)

该函数分配 2^{order} 个连续的物理页,并返回一个指针,指向第一个页的 page 结构体。出错则返回 NULL。

可以用下面这个函数把给定的页的 page 转换成它的逻辑地址:

void *page_address(struct page *page)

该函数返回一个指针,指向给定物理页当前所在的逻辑地址。

当你不在需要页时可以用下面的函数释放它们:

void __free_pages(struct page *page, unsigned int order)
void free_pages(unsigned long addr, unsigned int order)
void free_page(unsigned long addr)

四、kmalloc()

kmalloc() 函数与用户空间的 malloc() 类似,不过它多了一个 flags 参数,这个函数可以获得以字节为单位的一块内核内存。其在 <linux/slab.h> 中声明:

void *kmalloc(size_t size, gfp_t flags)

这个函数返回一个指向 size 大小的内存块指针,并且所分配的内存区在物理地址上是连续的(虚拟地址自然也是连续的)。出错时则返回 NULL。

使用 kfree() 函数可以释放由 kmalloc() 分配出来的内存块:

void kfree(const void *ptr)

如果想要释放的内存不是由 kmalloc() 分配的,或者想要释放的内存早就被释放了,调用这个函数就会有很严重的后果。

五、vmalloc() 

vmalloc() 函数类似于 kmalloc(),但是 vmalloc() 函数分配的内存虚拟地址是连续的,而物理地址则无需连续。malloc() 函数也一样,其在虚拟地址空间内是连续的,但是并不保证它们在物理 RAM 中也是连续的。

void *vmalloc(unsigned long size)
void vfree(const void *addr)

大多数情况下,只有硬件设备用到的内存区必须是物理上连续的块。而供软件使用的内存块就可以使用只有虚拟地址连续的内存块。

六、slab 分配器

分配和释放数据结构是所有内核中最普遍的操作之一,空闲链表包含可供使用的、已分配好的数据结构块,当代码需要一个新的数据结构实例时,就可以从空闲链表中抓取一个,而不需要重新分配内存。空闲链表相当于对象高速缓存,可以快速存储频繁使用的对象类型。

但空闲链表无法全局控制,当可用内存紧缺时,内核无法通知每个空闲链表,让其释放一些内存。所以为了弥补这一缺陷,Linux 内核提供了 slab 层(slab 分配器)slab 分配器扮演了通用数据结构缓存层的角色

  • 下面是 slab 分配器的基本原则:
  • 频繁使用的数据结构应该缓存它们。
  • 频繁分配和回收会导致内存碎片化,为了避免这种情况,空闲链表的缓存会连续地存放,释放的数据结构又会放回空闲链表。
  • 回收的对象可以立即投入下一次分配。
  • 对存放对象进行着色(color),以防止多个对象映射到相同的高速缓存行(cache line)。

slab 分配器把不同的对象划分为不同的高速缓存组,每个高速缓存组都存放不同类型的对象。比如,一个高速缓存用于存放进程描述符(task_struct 结构的一个空闲链表),一个用于存放索引节点对象(struct inode)。

然后,这些高速缓存又被划分为多个 slab,slab由一个或多个物理上连续的页组成。每个 slab 都包含一些被缓存的数据结构,并且每个 slab 都处于三种状态之一:满、部分满或空(注意这里满的意思是所有的数据结构都被使用中,无法分配)。当内核的某一部分需要一个新的对象时,先从部分满的 slab 中进行分配,其次再从空的 slab 中进行分配,如果没有空的 slab,那么就需要创建一个新 slab了。

下面是三者之间的关系:

slab 负责内存紧缺情况下所有底层的对齐、着色、分配、释放和回收,如果要频繁的创建很多相同类型的对象,那么就应该考虑使用 slab 高速缓存。

七、在栈上的静态分配

用户空间能负担起非常大的栈,而且栈空间还能动态增长,但内核却不能这么奢侈,内核栈小而且固定。当给每个进程分配一个固定大小的栈后,不但可以减小内存的消耗,而且内核也无需负担太重的栈管理任务。

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

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

相关文章

网工内推 | 锐捷招云工程师,HCIE、CCIE、RHCE优先,25k*13薪

01 锐捷网络 招聘岗位&#xff1a;云方案工程师 职责描述&#xff1a; 1、负责云数据中心方案项目方案设计撰写、项目实施交付、故障处理、业务割接、客户培训、现场保障、网络优化、网络巡检等技术相关业务 2、负责云数据中心方案新技术文档沉淀、体系建设、工具开发等标准化…

使用element-plus组件,默认显示英文 转换为中文

最近在边写项目边学习vue3 所以这几天没有更新 找机会把vue3的知识也统计一下吧 先说今天遇到的问题 最近做项目的时候使用element-plus分页组件时发现&#xff0c;显示的不是中文的了&#xff0c;是英文的 解决方法 在app.vue里面配置 <template><el-config-provi…

Pyqt5打开电脑摄像头进行拍照

目录 1、设计UI界面 2、设计逻辑代码&#xff0c;建立连接显示窗口 3、结果 1、设计UI界面 将ui界面转为py文件后获得的逻辑代码为&#xff1a;&#xff08;文件名为 Camera.py&#xff09; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file …

【算法专题突破】双指针 - 移动零(1)

目录 写在前面 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 写在前面 在进行了剑指Offer和LeetCode hot100的毒打之后&#xff0c; 我决心系统地学习一些经典算法&#xff0c;增强我的综合算法能力。 1. 题目解析 题目链接&#xff1a;283. 移动零 - 力…

centos7.9和redhat6.9 离线升级OpenSSH和openssl (2023年的版本)

升级注意事项&#xff01; 1、多开几个连接窗口&#xff08;xshell&#xff09;&#xff0c;避免升级openssh失败无法再次连接终端&#xff0c;否则要跑机房了。 2、可开启telnet服务、vnc服务、打快照。多几个“保命”的路数。一、centos7.9的信息 [rootnode2 ~]# openssl v…

学会Mybatis框架:一文掌握MyBatis与GitHub插件分页的完美结合【三.分页】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Mybatis的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Mybatis分页 1. Mybatis自带分页 2…

AIGC如何借AI Agent落地?TARS-RPA-Agent破解RPA与LLM融合难题

文/王吉伟 大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;的持续爆发&#xff0c;让AIGC一直处于这股AI风暴最中央&#xff0c;不停席卷各个领域。 在国内&#xff0c;仍在雨后春笋般上新的大语言模型&#xff0c;在持续累加“千模大战”大模型数量的…

Linux之基础IO文件系统讲解

基础IO文件系统讲解 回顾C语言读写文件读文件操作写文件操作输出信息到显示器的方法stdin & stdout & stderr总结 系统文件IOIO接口介绍文件描述符fd文件描述符的分配规则C标准库文件操作函数简易模拟实现重定向dup2 系统调用在minishell中添加重定向功能 FILE文件系统…

什么是Pytorch?

当谈及深度学习框架时&#xff0c;PyTorch 是当今备受欢迎的选择之一。作为一个开源的机器学习库&#xff0c;PyTorch 为研究人员和开发者们提供了一个强大的工具来构建、训练以及部署各种深度学习模型。你可能会问&#xff0c;PyTorch 是什么&#xff0c;它有什么特点&#xf…

为什么需要单元测试?

为什么需要单元测试&#xff1f; 从产品角度而言&#xff0c;常规的功能测试、系统测试都是站在产品局部或全局功能进行测试&#xff0c;能够很好地与用户的需要相结合&#xff0c;但是缺乏了对产品研发细节&#xff08;特别是代码细节的理解&#xff09;。 从测试人员角度而言…

Mysql简短又易懂

MySql 连接池:的两个参数 最大连接数&#xff1a;可以同时发起的最大连接数 单次最大数据报文&#xff1a;接受数据报文的最大长度 数据库如何存储数据 存储引擎&#xff1a; InnoDB:通过执行器对内存和磁盘的数据进行写入和读出 优化SQL语句innoDB会把需要写入或者更新的数…

Java如何调用接口API并返回数据(两种方法)

Java如何调用接口API并返回数据&#xff08;两种方法&#xff09; java处理请求接口后返回的json数据-直接处理json字符串 处理思路&#xff1a; 将返回的数据接收到一个String对象中&#xff08;有时候需要自己选择性的取舍接收&#xff09; 再将string转换为JSONObject对象 …

Go 语言在 Windows 上的安装及配置

1. Go语言的下载 Golang官网&#xff1a;All releases - The Go Programming Language Golang中文网&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 两个网站打开的内容只有语言不同而已&#xff0c;网站上清晰的标注了不同操作系统需要对应安装哪个版本&#xff0c;其中…

港联证券|燃气板块午后走高,美能能源涨停,水发燃气大幅拉升

燃气板块21日午后快速拉升&#xff0c;到发稿&#xff0c;美能动力涨停&#xff0c;水发燃气涨超7%&#xff0c;蓝天燃气涨超5%&#xff0c;贵州燃气涨逾4%。 消息面上&#xff0c;受澳大利亚LNG工厂罢工忧虑影响&#xff0c;欧洲基准天然气价格一度大涨18%。 有报导称&#x…

npm报错:xxx packages are looking for funding run `npm fund` for details(解决办法)

报错信息&#xff1a;30 packages are looking for funding run npm fund for details 报错原因&#xff1a;这里是开发者捐赠支持的提示&#xff0c;打开一个github的链接之后&#xff0c;会显示是否需要打赏捐赠的信息。 解决方案&#xff1a;这个打赏是资源的&#xff0c;因…

YOLOV8 win10部署笔记

文章目录 1. 背景2. 部署过程2.1 快速安装 1. 背景 看了B站许多up主的视频&#xff0c;感觉YOLOV8各方面都很优秀&#xff0c;作为新手对它的期待很大&#xff0c;于是想实际跑跑看&#xff0c;边实践&#xff0c;边学习&#xff0c;记录过程。 本篇主要是博主在windows平台上…

控制Unity发布的PC包的窗体

大家好&#xff0c;我是阿赵。   用Unity发布PC包接入某些渠道时&#xff0c;有时候会收到一些特殊的需求&#xff0c;比如控制窗口最大化(比如某些情况强制显示窗体)、最小化(比如老板键)、强制规定窗体置顶等。虽然我一直认为这些需求都是流氓软件行为&#xff0c;但作为一…

[管理与领导-43]:IT基层管理者 - 个人管理 - 管理中从角色定位迈步

前言&#xff1a; 管理者的“四位” &#xff1a; ‣ 定位——在什么位置做什么事情&#xff1b; ‣ 到位——全力以赴把事情做好&#xff1b; ‣ 不越位——不要把别人的工作做了&#xff1b; ‣ 补位——同事临时“缺位” &#xff0c;及时补位&#xff0c;提升效率&…

Linux:shell脚本:基础使用(6)《正则表达式-awk工具》

简介 awk是行处理器: 相比较屏幕处理的优点&#xff0c;在处理庞大文件时不会出现内存溢出或是处理缓慢的问题&#xff0c;通常用来格式化文本信息 awk处理过程: 依次对每一行进行处理&#xff0c;然后输出 1&#xff09;awk命令会逐行读取文件的内容进行处理 2&#xff09;a…

clickhouse-压测

一、数据集准备 数据集可以使用官网数据集&#xff0c;也可以用ssb-dbgen来准备 1.准备数据 这里最后生成表的数据行数为60亿行&#xff0c;数据量为300G左右 git clone https://github.com/vadimtk/ssb-dbgen.git cd ssb-dbgen/ make1.1 生成数据 # -s 指生成多少G的数据…