
Linux 内存管理
文章平均质量分 97
本专栏用以整理内存开发、维护过程中的知识点和开发经验。
本专栏内容基于Linux5.4、Linux5.10、Linux5.15、Linux6.6 源码,剖析整个内存管理的原理,剖析整个代码流程,并通过详细的框架图、时序图、流程图,帮助各个模块知识点理解。
此专栏会长期、持续的整理内存相关知识点!
优惠券已抵扣
余额抵扣
还需支付
¥179.90
¥299.90
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
私房菜
独乐乐不如众乐乐!!!!
展开
-
Linux 内存管理总续
还是习惯性的以前言开篇,“深入骨髓”的程序猿思想,干啥事都想从main 开始~~在Android 项目中接触内存管理相关的有一段时间了,中间看了很多代码,看了忘,忘了看,反反复复,索性就抽点时间整理出来~~该专栏通过剖析 Linux 5.4 版本的源码,尽可能清晰、完整地总结内存管理相关的知识点,进而展示Linux 内存管理的所有模块的原理。该专栏中的原理会在持续、长期、反复地的剖析中进行补充说明。原创 2022-06-21 11:01:49 · 1254 阅读 · 14 评论 -
Linux内存管理(外四):page table
在中有个 PageTables 的属性值,该属性值具体统计的是哪些内存呢?在用户层的虚拟内存与物理内存映射时,是怎么样的映射方式?如何通过虚拟地址找到手机的物理地址?在内存老化、回收时,系统如何扫描,又如何通过扫描页表识别冷、热页?页表查询过程简述TTBRn:由虚拟地址最高位 bit[63] 决定,如果该位为 1,表示这个地址用于内核空间,页表的基地址寄存器用TTBR1;若该位为0,表示这个地址属于用户空间,页表的基地址寄存器用 TTBR0。原创 2025-03-26 16:26:41 · 476 阅读 · 0 评论 -
Linux内存管理(外三):zero page
在实际应用程序场景中,经常存在其虚拟内存已经申请,且只对该内存进行读取过,但是从未对该内存进行过写操作,如果针对此场景发生只读page fault时,也为其虚拟内存区域全部申请对应物理内存将会极大浪费内存 因为后面从没有对该内存真正进行写过。当内存先读后写时,会触发两次page fault,先触发读内存page fault 使用zero page刷新对应映射,然后由于写内存会再次触发 page fault才生成新的实际物理内存,相对之前一次触发page fault,消耗可能会增多。原创 2025-03-02 15:11:44 · 70 阅读 · 0 评论 -
Linux内存管理(外二):struct page 成员参数详解
当alloc_pages() 分配page 后,后面每一个引用该 page 的用户,都需要通过 get_page()将此 page->_refcount++,代表再多一个用户使用该 page。站在buddy 分配器的角度来看,此时的 pages 相当于被分配出去,memblock 在使用所有的pages。在 buddy 分配器初始化时,从memblock_free_all() -> __free_pages_core() -> set_page_count() 将。用以初始化 _refcount 为 1;原创 2025-02-12 11:27:00 · 381 阅读 · 0 评论 -
Linux内存管理(外一):mlock 与 Unevictable
同 mlock(),这里也是通过 apply_vma_lock_flags() 修改 vma->vm_flags,只不过 mlock() 带入的是 VM_LOCKED,而这里是0.该demo 使用 mlock 确认memory 的统计,申请了 10M 的内存,并通过 mlock() 进行锁定,确认这部分内存的归属。锁定的内存都会被计入/proc/meminfo 中的Mlocked,同时也会计入到。原创 2025-02-08 10:58:56 · 272 阅读 · 0 评论 -
Linux内存管理(八十四):Page Extension 详解
为了动态使用 page extension 的扩展功能,这里的结构体数组 page_ext_ops 将包含所有的扩展功能,而系统通过 page extension 实际使能的扩展功能,则通过各扩展功能的 need callback,详细查看下文 invoke_need_callback() 函数。在page_ext 初始化时,在函数 invoke_need_callbacks() 中统计 page_ext_ops 数组中支持的所有扩展功能占用的大小,也就是page_ext 的大小。原创 2025-03-31 07:07:08 · 314 阅读 · 0 评论 -
Linux内存管理(八十三):Memory allocation profiling 原理简介
Memory allocation profiling 是 Linux 6.12 中的重要功能。帮助开发者和系统管理员理解内存的使用情况,在MAP 中每一次的内存分配都可以精确地追溯到具体的代码行,可以轻松地识别分配的源头。无论是内核代码还是需要加载的模块代码。原创 2025-03-23 11:11:26 · 457 阅读 · 0 评论 -
Linux内存管理(八十二):内存检测工具 kfence(2)
kfence虽然代码不多,但设计的内容、逻辑比较多。第一篇重在kfence 基础数据结构、kfence初始化、kfence内存分配和释放;第二篇重在kfence 缺页异常剖析、kfence report剖析、测试框架剖析、具体案例分析;原创 2023-10-26 11:03:23 · 507 阅读 · 0 评论 -
Linux内存管理(八十一):内存检测工具 kfence(1)
本文 kfence 之外的代码版本是基于 Linux5.10,最近需要将 kfence 移植到 Linux5.10 中,本文借此机会将 kfence 机制详细地记录一下。kfence,全称为,是 Linux5.12 版本新引入的内存使用错误检测机制。kfence 基本原理非常简单,它创建了自己的专有检测内存池 kfence_pool。然后在 data page 的两边加上 fence page 电子栅栏,利用 MMU 的特性把 fence page 设置为不可访问。原创 2023-10-24 16:34:28 · 795 阅读 · 0 评论 -
Linux内存管理(八十):内存管理可能出现的bug和panic
源码基于:Linux 5.4 在之前的博文《Linux内核oops panic简析》中简单分析Linux 内核异常处理的流程。本文在此基础上总结下内存管理系统中(针对arm64架构)可能出现的BUG 或 oops 或panic,并对这些情况进行剖析。因为涉及到的BUG 场景不一定相同,本篇博文应该是一个长期整理的过程。这个是编译时候就需要检验的,如果condition 为 false,会停掉编译,并发出error msg 打印。BUG_ON() 同BUG(),只不过是有condition 检查,原创 2023-05-23 15:26:31 · 961 阅读 · 0 评论 -
Linux内存管理(七十六):memcg v1 简介
全局 LRU 会swap out 任意的页数,swap out 意味着内存搬移到swap,对于memory +swap 是没有变化的。也就是说,当我们想限制swap 使用而没有影响全局 LRU,-站在操作系统的角度,限制 memory+swap 要比限制swap 好。原创 2024-06-28 10:13:08 · 702 阅读 · 0 评论 -
Linux内存管理(七十五):memcg v2 简介
memory.swap.high与max 略微不同,当cgroup 的swap使用量达到该 limit,将对cgroup 的分配进行节流,以允许用户空间实现自定义内存不足的过程。如果cgroup的内存使用量在该值下限内,则该cgroup 的内存将不会被回收,除非不受保护的cgroup中没有可用的可回收内存。如果在该 cgroup 中调用OOM killer,则无论其祖先 cgroup的 memory.oom.group为何值,都不会kill 该cgroup 以外的任何tasks。原创 2024-06-27 15:48:05 · 715 阅读 · 0 评论 -
Linux内存管理(七十四):cgroup v2 简介
术语:cgroup:control group 的缩写,永不大写(never capitalized);单数形式的 cgroup 用于指定整个特性,也用作等术语中的修饰符;复数形式的 cgroups 显式指多个独立的;cgroup 是一种机制,它将系统进程按照分层组织,并沿着这种分层以一个可控、可配置的方式来分配系统资源。原创 2024-06-27 10:17:23 · 489 阅读 · 0 评论 -
Linux内存管理(七十三):Linux PSI 详解(3)
在《PSI 详解(2)》上一文中详细剖析了 PSI 初始化过程、数据采集过程、状态更新过程,也将cgroup 关于PSI 的注意点和流程一并整理。本文将继续上文,重点剖析 PSI 接下来对于数据的统计过程,包括对每个 psi_trigger 的poll 机制的响应,以及显示需要的运行平均值计算。负责 psi trigger 的polling 功能,入口函数为 psi_schedule_poll_work();原创 2024-11-14 14:29:27 · 303 阅读 · 0 评论 -
Linux内存管理(七十二):Linux PSI 详解(2)
在《PSI 详解(1)》上一文中整理的 PSI 的原理和一些重要的数据结构,本文将在其基础上,详细剖析 PSI 初始化过程、数据采集过程、数据统计过程,也将cgroup 关于PSI 的注意点和流程一并整理。PSI 功能依赖CONFIG_PSI,当该 config 没有使能,psi.c是不会被编译到 image的。原创 2024-05-29 19:00:15 · 1323 阅读 · 0 评论 -
Linux内存管理(七十一):Linux PSI 详解(1)
之前在《Linux PSI 指标》一文中简单的描述了 PSI 指标的意义,以及PSI 出现的历史过程。在PSI 之前,Linux 也有一些资源压力的评估方法,最具代表性的是和而 load average 和vmpressure 都有各自的缺陷。详细可以查看《Linux PSI 指标》一文。PSI,是PressureStallInformation 简称,是识别并量化 CPU、IO、memory 等资源紧张造成的中断,及其它对复杂工作负载甚至整个系统的时间影响。原创 2022-10-24 20:43:56 · 2990 阅读 · 4 评论 -
Linux内存管理(六十六):直接内存规整详解
在前一篇博文手动规整;kcompactd 内核线程规整;直接内存规整;前两种方式已经与Linux 内核参数:compaction一文和kcompactd详解一文剖析过,本文将继续剖析第三种规整方式——直接内存规整,以及规整处理的核心函数。原创 2022-09-21 14:37:50 · 1104 阅读 · 0 评论 -
Linux内存管理(六十五):kcompactd详解
伙伴系统以页面为单位来管理内存,内存碎片也是基于页面的,即由大量离散且不连续的页面组成的。从内核角度来看,出现内存碎片不是好事情,有些情况下物理设备需要大段的连续的物理内存,如果内核无法满足,则会发生内核错误。内存规整就是为了解决内核碎片化而出现的一个功能。内核中去碎片化的基本原理是按照页面的可移动性将页面分组。迁移内核本身使用的物理内存的实现难度和复杂度都很大,因此目前的内存不迁移内核本身使用的物理页面。原创 2022-09-20 17:18:59 · 1891 阅读 · 0 评论 -
Linux内存管理(六十四):内存规整简介
伙伴系统以页面为单位来管理内存,内存碎片也是基于页面的,即由大量离散且不连续的页面组成的。从内核角度来看,出现内存碎片不是好事情,有些情况下物理设备需要大段的连续的物理内存,如果内核无法满足,则会发生内核错误。内存规整就是为了解决内核碎片化而出现的一个功能。内核中去碎片化的基本原理是按照页面的可移动性将页面分组。迁移内核本身使用的物理内存的实现难度和复杂度都很大,因此目前的内存不迁移内核本身使用的物理页面。原创 2023-02-13 11:06:33 · 842 阅读 · 0 评论 -
Linux内存管理(六十一):页面回收总结
在页面回收简介和 kswapd详解(1)一文中简单列举了Linux 内核中触发页面回收的机制,详细剖析了 kswapd 内核线程的初始化和唤醒过程,了解了唤醒 kswapd 内核线程的 3 种方式。图1是直接内存回收唤醒 kswapd 的大致流程。在kswapd详解(2)一文中详细地剖析了唤醒 kswapd 内核线程后,线程核心处理函数 kswapd() 的执行过程和注意点。图2是唤醒kswapd 和 kswapd() 处理的大致流程。在shrink_node 详解。原创 2022-09-14 15:22:23 · 1232 阅读 · 0 评论 -
Linux内存管理(六十):内核OOM机制详解
在 buddy系统慢速分配 一文中,我们分析了从快速分配流程无法分配到内存之后,会进入慢速分配流程。通过降低水位等方式修改 alloc_flags,尝试唤醒kswapd,并尝试再次分配;修改ac 的nodemask,并再次尝试分配;直接内存回收之后的尝试分配;直接内存规整之后的尝试分配;reclaim retry、compact retry 之后的尝试分配;如果经过这些努力之后还是无法分配到内存时,内核采取最后的极端分配:OOM。原创 2022-10-19 15:06:34 · 1664 阅读 · 0 评论 -
Linux内存管理(五十九):直接内存回收详解
在页面回收简介直接页面回收机制周期性回收内存机制(kswpad)slab 收割机在kswapd 详解一文第2.2此方式来自快速分配时发现当前 migrate type 中没有页面,但是能从其他 migrate type 中 steal 页面出来时,认为系统存在碎片,需要唤醒 kswapd 进行回收;此方式来自慢速分配,当通过快速分配方式之后,无法分配出pages,分配器进行慢速申请。原创 2022-09-30 17:08:44 · 1501 阅读 · 0 评论 -
Linux内存管理(五十八):PageAnon 与 PageSwapBacked
从其他一些博文中,总是说 PageAnon 表示匿名页,PageSwapBacked 也表示匿名页,但其实这两个函数还是有明显的概念区别的。本文将结合代码,详细分析这两个函数的使用场景。!原创 2022-09-16 11:30:19 · 1171 阅读 · 0 评论 -
Linux内存管理(五十七):shrink_list 详解(2)
在上一篇博文中详细分析了部分中的和详细流程见代码注释,这里有几个重点下面单独拉出来剖析。原创 2022-09-07 17:55:48 · 863 阅读 · 0 评论 -
Linux内存管理(五十六):shrink_list 详解(1)
在在一文主要分析了 shrink_lruvec,并知道在get_scan_count() 中根据扫描平衡条件,确定了anon/file LRU 扫描页数,并最终会 shrink_list() 进行深入的回收处理。本文将继续分析页面回收 shrink_lruvec() 部分的和流程。原创 2022-09-06 21:50:47 · 1005 阅读 · 0 评论 -
Linux内存管理(五十五):shrink_node 详解
在页面回收简介和 kswpd(1)直接页面回收机制:在内核态里调用页面分配接口函数 alloc_pages() 分配物理页面时,由于系统内存短缺,不能满足分配请求,因此内核会直接进入页面回收机制,尝试回收内存来解决当前的燃眉之急,这就是直接页面回收机制。周期性回收内存机制:这是 kswapd 内核线程的工作职责。当内核路径调用 alloc_pages() 分配物理页面时,由于系统内存短缺,没法在低水位情况下分配出内存,因此会唤醒 kswapd 内核线程来异步回收内存。原创 2022-09-05 20:04:32 · 3656 阅读 · 0 评论 -
Linux内存管理(五十四):kswapd详解(2)
在上一篇博文出现内存碎片时的临时唤醒;内存严重短缺时的唤醒;直接页面回收中的唤醒;kswapd 内部启动的schedule;在上一篇博文中,同样也对 kswapd 所涉及的数据结构、初始化过程进行详细的剖析,本文将继续上一篇博文,详细剖析 kswapd 执行函数到页面回收的整个流程。..................原创 2022-08-30 21:56:03 · 1213 阅读 · 0 评论 -
Linux内存管理(五十三):页面回收简介和 kswapd详解(1)
在LRU简介一文和LRU 第二次机会法一文中,提到当内存出现紧张的时候,会将 inactive list 尾部的 page 进行换出,从而将page 释放回buddy free list中(如果有引用则会给第二次机会)。换出(swap-out),把进程暂时不用的内存数据(anon page)存储到磁盘中,并释放这些数据占用的内存。换入(swap-in),进程再次访问这些内存时,将数据从磁盘中读到内存中直接页面回收机制周期性回收内存机制slab 收割机。............................原创 2022-08-30 15:17:20 · 1566 阅读 · 3 评论 -
Linux内存管理(五十二):LRU 第二次机会法
在经典 LRU 链表算法中,新产生的页面被添加到 LRU 链表的开头,将 LRU 链表中存在的页面向后移动一个位置。当系统内存短缺时,LRU 链表尾部的页面将会离开并被换出。当系统再需要这些页面时,这些页面会被重新置于 LRU 链表的开头。显然这个设计不是很巧妙,在换出页面时,没有考虑页面是否频繁使用。也就是说,频繁使用的页面依然会因为在 LRU 链表末尾而被换出。...........................原创 2022-08-26 18:20:09 · 1087 阅读 · 0 评论 -
Linux内存管理(五十一):LRU简介
在Linux 操作系统中,当内存充足时,内核会尽量多地使用内存作为文件缓存(page cache),从而提高系统的性能。文件缓存页面会添加到文件类型的 LRU 链表中。当内存紧张时,文件缓存页面会被丢弃,或者把修改的文件缓存页面回写到存储设备中,与块设备同步之后便可释放出物理内存。现在的应用程序转向内存密集型,无论系统中有多少物理内存都是不够用的,因此Linux 系统会使用存储设备作为交换分区,内核将很少使用的内存换出到交换分区,以便释放出物理内存,这个机制称为页交换(swapping)..........原创 2022-08-25 22:41:50 · 1478 阅读 · 0 评论 -
Linux内存管理(四十六):ION 内存管理器——system heap
ION是 Google 在 Android 4.0 中引入,目的主要是通过在硬件设备和用户空间之间分配和共享内存,实现设备之间零拷贝共享内存,多用于多媒体,比如 camera、display、graphic等。ION是一个内存管理器,管理不同type的内存堆(heap),而不同的type的内存又通过不同的内存分配器来分配,比如cma、kmalloc、vmalloc等。通过《ION 总篇》原创 2023-11-28 21:50:29 · 1621 阅读 · 0 评论 -
Linux内存管理(四十五):ION 内存管理器——cma heap
ION是 Google 在 Android 4.0 中引入,目的主要是通过在硬件设备和用户空间之间分配和共享内存,实现设备之间零拷贝共享内存,多用于多媒体,比如 camera、display、graphic等。ION是一个内存管理器,管理不同type的内存堆(heap),而不同的type的内存又通过不同的内存分配器来分配,比如cma、kmalloc、vmalloc等。通过《ION 总篇》原创 2023-11-28 21:45:44 · 1435 阅读 · 0 评论 -
Linux内存管理(四十四):ION 内存管理器——总篇
ION是 Google 在 Android 4.0 中引入,目的主要是通过在硬件设备和用户空间之间分配和共享内存,实现设备之间零拷贝共享内存,多用于多媒体,比如 camera、display、graphic等。ION是一个内存管理器,管理不同type的内存堆(heap),而不同的type的内存又通过不同的内存分配器来分配,比如cma、kmalloc、vmalloc等。原创 2023-04-28 23:13:50 · 1979 阅读 · 0 评论 -
Linux内存管理(四十三):vmalloc 详解
kmalloc()、vmalloc()、malloc() 这三个函数是常用的内存分配函数,但有着本质的区别。kmalloc()基于slab 分配器,是建立在一个物理地址连续的大内存块上,所以 kmalloc() 分配的内存物理是上连续的,而且 kmalloc() 映射的虚拟内存在线性区域,也是连续的。详细可以查看《slub 分配器之kmem_cache_alloc》一文第5.1.2节。相比于 kmalloc(),vmalloc()实现是为了虚拟内存连续,而物理内存可以不用连续。原创 2023-04-17 20:55:14 · 1384 阅读 · 0 评论 -
Linux内存管理(四十二):CMA 分配器——分配原理
上一篇博文是延续《memblock初始化》一文,对 dts 中 reserved-memory 节点进行详细剖析,阐述 CMA 分配器中核心数组 cma_areas 的创建过程。本文将重点剖析 CMA 分配器的分配、释放流程,对应接口是 cma_alloc() 函数、cma_release() 函数。将 cma 分配过程通过 5 张图阐述总结,核心逻辑都在图1,此时 CMA 的内存正在被非 cma 驱动使用,其中绿色表示普通页面,紫色表示干净的文件页,此时内存还是 MIGRATE_CMA 类型;图2,原创 2024-01-08 16:42:14 · 1249 阅读 · 0 评论 -
Linux内存管理(四十一):CMA 分配器——区域创建
在一文,我们得知某些特定的设备在使用时需要大量的连续物理内存,系统为了这个目的特定提供了机制,这样为某些特定的设备提供了预留内存。但是,这样有个明显的确定:因为这些预留内存不能被系统管理使用,在设备不启动的时候,这部分内存无法被利用,这样就造成了内存利用率的降低。此时诞生了 CMA 机制,当设备在不启动时,可以将这部分内存交给系统正常分配,而在设备需要使用时,则将这部分内存交给绑定的设备使用。这样大大地提高了内存的利用率。CMA(,称为连续内存分配器,用于分配连续的大块内存。原创 2023-04-25 22:06:11 · 1346 阅读 · 0 评论 -
Linux内存管理(三十八):slub 分配器之kmalloc详解
在之前的 slub 系列博文中,详细地分析了slub 分配的初始化、创建、对象分配、对象释放的原理, linux 系统为内核一些连续内存申请提供了 kmalloc 接口,为此专门创建了不同大小的kmalloc caches,详细可以查看《slub 分配器初始化》第5节。本文在此基础上详细分析 kmalloc 相关接口。原创 2022-12-01 19:37:58 · 927 阅读 · 0 评论 -
Linux内存管理(三十七):slub 分配器之kmem_cache_destroy
在博文《slub分配器之kmem_cache_create》中详细分析了使用对外接口申请slab cache 的过程,在博文《slub分配器之kmem_cache_alloc》中详细分析了通过slab cache 分配object 的分配过程,了解了slub 分配器分配内存的快速分配和慢速分配两种方式。在博文《slub 分配器之kmem_cache_free》中详细分析了slab cache分配出去的对象的释放过程,剖析了slub 分配器内存释放的快速、慢速过程。原创 2022-11-30 15:37:27 · 814 阅读 · 0 评论 -
Linux内存管理(三十六):slub 分配器之kmem_cache_free
在博文《slub分配器之kmem_cache_create》中详细分析了使用对外接口申请slab cache 的过程,在博文《slub分配器之kmem_cache_alloc》中详细分析了通过slab cache 分配object 的分配过程,了解了slub 分配器分配内存的快速分配和慢速分配两种方式。本文将重点分析slub 分配对外的第三个接口 kmem_cache_free(),该接口用以释放slub 缓存对象。原创 2022-11-24 10:28:43 · 850 阅读 · 0 评论 -
Linux内存管理(三十五):slub 分配器之kmem_cache_create
slub 分配器初始化》一文中我们详细分析了slub 分配的初始化流程,最开始slub 系统没创建好,系统利用了局部变量和,临时创建了两个slab,创建完成后使用将全局变量和管理结构迁入,摆脱静态局部变量管理,至此slub 系统初步形成。紧接着通过创建kmalloc 需要的 slab caches(大概14组),此时通过更新为UP,标记slub 系统正式创建完成。原创 2022-11-23 12:25:23 · 753 阅读 · 0 评论