Linux内核源码分析之内存管理

Linux内核之 内存管理 前面几篇介绍了进程的一些知识,从这篇开始介绍内存、文件、IO等知识,发现更不好写哈哈。但还是有必要记录下自己的所学所思。供后续翻阅,同时写作也是一个巩固的过程。 这些知识以前有文档涉及过,但是角度不同,这个系列站的角度更底层,基本都是从Linux内核出发,会更深入。所以当你都读完,然后再次审视这些功能的实现和设计时,我相信你会有种豁然开朗的感觉。 1、页 内核把物理页作为内存管理的基本单元。 尽管处理器的最小处理单位是字(或者字节),但是MMU(内存管理单元,管理内存并把虚拟地址转换为物理地址的硬件)通常以 阅读详情

本文站的角度更底层,基本都是从Linux内核出发,会更深入。所以当你都读完,然后再次审视这些功能的实现和设计时,我相信你会有种豁然开朗的感觉。

1、页

内核把物理页作为内存管理的基本单元。

尽管处理器的最小处理单位是字(或者字节),但是MMU(内存管理单元,管理内存并把虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。所以从虚拟内存看,页也是最小单元。

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

内核用struct page结构体表示系统中的每个页,包含很多项比如页的状态(有没有脏,有没有被锁定)、引用计数(-1表示没有使用)等等。

page结构和物理页相关,和虚拟内存无关。所以它的描述是短暂的,仅仅记录当前的使用状况,当然也不会描述其中的数据。

内核用这个结构来管理系统中所有的页,所以内核知道哪些页是空闲的,如果在使用中拥有者又是谁。

这个拥有者有四种:用户空间进程、动态分配内存的内核数据、静态内核代码以及页高速缓存。

2、区

有些页是有特定用途的。比如内存中有些页是专门用于DMA的。

内核使用区的概念将具有相似特性的页进行分组。区是一种逻辑上的分组的概念,而没有物理上的意义。

区的实际使用和分布是与体系结构相关的。在x86体系结构中主要分为3个区:ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM。

ZONE_DMA区中的页用来进行DMA(直接内存访问)时使用。

ZONE_HIGHMEM是高端内存,其中的页不能永久的映射到内核地址空间,也就是说,没有虚拟地址。

剩余的内存就属于ZONE_NORMAL区,叫低端内存。

不是所有体系都定义全部区,有些体系结构,比如x86-64可以映射和处理64位的内存空间,所以它没有ZONE_HIGHMEM区,所有的物理内存都都处于ZONE_DMA和ZONE_NORMAL区。

每个区都用结构体struct zone表示。

3、接口

获得页

获得页使用的接口是alloc_pages函数与__get_free_page函数。后者也是调用了前者,只不过在获得了struct page结构体后使用page_address函数获得了虚拟地址。

我们在使用这些接口获取页的时候可能会面对一个问题,我们获得的这些页若是给用户态用,虽然这些页中的数据都是随机产生的垃圾数据,不过,虽然概率很低,但是也有可能会包含某些敏感信息。所以,更谨慎些,我们可以将获得的页都填充为0。这会用到get_zeroed_page函数。而这个函数又用到了__get_free_pages函数。

所以这三个函数最终都是使用了alloc_pages函数。

释放页

当我们不再需要某些页时可以使用下面的函数释放它们:
__free_pages(struct page *page, unsigned int order)
free_pages(unsigned long addr, unsigned int order)
free_page(unsigned long addr)

以上这些接口都是以页为单位进行内存分配与释放的。

kmalloc与vmalloc

在实际中内核需要的内存不一定是整个页,可能只是以字节为单位的一片区域。这两个函数就是实现这样的目的。

不同之处在于,kmalloc分配的是虚拟地址连续,物理地址也连续的一片区域,vmalloc分配的是虚拟地址连续,物理地址不一定连续的一片区域。

对应的释放内存的函数是kfree与vfree。

4、slab层

以页为最小单位分配内存对于内核管理系统中的物理内存来说的确比较方便,但内核自身最常使用的内存却往往是很小的内存块——比如存放文件描述符、进程描述符、虚拟内存区域描述符等行为所需的内存都远不及一页,一个整页中可以聚集多个这些小块内存。

为了满足内核对这种小内存块的需要,Linux系统采用了一种被称为slab分配器(也称作slab层)的技术。slab分配器的实现相当复杂,但原理不难,其核心思想就是“存储池”的运用。内存片段(小块内存)被看作对象,当被使用完后,并不直接释放而是被缓存到“存储池”里,留做下次使用,这无疑避免了频繁创建与销毁对象所带来的额外负载。

slab分配器扮演了通用数据结构缓存层的角色。

slab层把不同的对象划分为所谓高速缓存组,其中每个高速缓存组都存放不同类型的对象,每种对象对应一个高速缓存。

常见的高速缓存组有:进程描述符(task_struct结构体),索引节点对象(struct inode),目录项对象(struct dentry),通用页对象等等。

这些高速缓存又被划分为slab。slab由一个或多个物理连续的页组成,一般仅仅由一页组成。每个高速缓存可以由多个slab(页)组成。

每个高速缓存都使用struct kmem_cache结构表示,这个结构包含三个链表:slabs_full、slabs_partial和slabs_empty,均放在kmem_list3结构体内。这些链表的每个元素为slab描述符即struct slab结构体

【Linux 内核源码分析】内存管理——Slab 分配器 Slab 分配器 在Linux内核中,伙伴分配器是一种内存管理方式,以页为单位进行内存的管理和分配。但是在内核中,经常会面临结构体内存分配问题,而这些结构体的大小通常是小于一页的。如果使用伙伴分配器来分配这些小内存,将造成很大的内存浪费。因此,为了解决这个问题,Sun公司的Jeff Bonwick在Solaris 2.4中设计并实现了一种新的内存分配器——slab分配器。 与伙伴分配器不同的是,slab 分配器以字节为单位来分配内存,并基于伙伴分配器的大内存进一步细分成小内存进行分配。也就是说,slab 分 阅读详情

相关推荐

Linux-0.11内核源码分析系列:内存管理copy_page_tables()函数分析

/* *Author : DavidLin *Date : 2014-11-22pm *Email : linpeng1577@163.com or linpeng1577@gmail.com *world : the city of SZ, in China *Ver : 000.000.001 *history : editor

linpeng1577的专栏 2251

linux内核那些事之brk机制

内核向用户层提供申请用户虚拟空间的两种机制除了mmap之外,另外一个就是brk机制,mmap主要控制虚拟空间mmap区域管理,而brk机制主要管理的是一个进行的堆空间。 brk/sbrk brk 和sbrk是内核向用户提供的两个用于申请堆空间的系统调用,一般应用程序并不直接使用brk系统调用,而是通过glibc封装好的malloc接口间接调用brk系统调用。 #include <unistd.h> int brk(void *addr); void *sbrk(intptr_t in

weixin_42730667的博客 5868

详解k-means++

一、概述 定义:k-means++是一种为k-means聚类算法选择初始值(或“种子”)的算法。它是NP-hard k-means问题的一种近似算法,它是一种避免标准k-means算法有时发现的较弱聚类的方法。 K-means与K-means++:原始K-means算法最开始随机选取数据集中K个点作为聚类中心,而K-means++按照如下的思想选取K个聚类中心:假设已经选取了n个初始聚类中心(0<n<K),则在选取第n+1个聚类中心时:距离当前n个聚类中心越远的点会有更高的概率被选为第n+1个聚

qq_42364307的博客 3万+

从硬件到软件:深度解析D435i USB SCP overflow错误的根源与解决方案

本文深入解析Intel RealSense D435i相机在ROS环境下常见的'USB SCP overflow'错误,特别是与`control_transfer`相关的错误提示。从硬件配置到软件优化,详细介绍了如何通过调整USB接口、优化`rs_camera.launch`参数、更新固件驱动等方法解决数据传输溢出问题,提升设备稳定性和性能。

yy01234的博客 771

极验第四代滑块验证码破解(三):滑块轨迹构造

极验第四代滑块验证码破解(三):滑块轨迹构造声明 声明 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码。维护网络安全,人人有责。 本文关联文章超链接:

帯泪的鱼的博客 8624

关于Win11安装Ubuntu子系统报错:WslRegisterDistribution failed with error 解决办法

Win11安装Ubuntu子系统报错:WslRegisterDistribution failed with error

qq_51908382的博客 3万+

华为无线AP+AC(ensp)

VLAN 100--192.168.100.0/24为AP的管理IP地址VLAN10--192.168.10.0/24为无线用户获取的IP地址在DHCP Server(LSW3)上查看地址分配情况。

abcdlalal的博客 1万+

Potplayer + LAVFilters + madVR 配置教程

文章目录Potplayer + LAVFilters + madVR 配置教程工具安装篇设置调教1.potplayer播放器设置加载LAVFilters和madVR1.选择“源滤镜/分离器”选项,选择“滤镜/解码器管理”2.“添加外部滤镜”3.浏览到刚才LAVFilters解压的文件夹,分别添加图示项。4.添加后回到管理界面设置,点击左边的”LAV AudioDecoder”,将右边”音频解码器”...

re 16万+

ROS2入门到精通—— 1-1 Linux和ROS2基础

本文介绍了Linux的一般指令以及ROS2的常见理论和操作

BigDavid123的博客 3804

【推荐100个unity插件】Animator 的替代品?—— Animancer Pro插件的使用介绍

Animancer与Unity Animator对比及使用指南 摘要: 本文对比了Animancer与Unity官方Animator的核心差异,分析了Animancer的优势特点。Animancer采用代码驱动模式,相比Animator的状态机系统更灵活高效,支持实时调试、动态混合和深度逻辑集成。文章详细介绍了Animancer的快速使用方法,包括动画播放、切换和触发机制,并区分了免费版与专业版的功能差异。适合需要高效动画开发、复杂交互逻辑的中小项目,为开发者提供了一种现代化的动画解决方案。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2434

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: Linux内核源码分析方法—程序员进阶必备
下一篇: Linux内核内存管理:地址转换和MMU
Linux服务器开发
博客等级 码龄7年 610粉丝 589原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值