Linux内存回收入口

news2024/9/28 21:22:16
概述

内存回收主要是有kswapd异步回收和direct reclaim同步回收两种入口,其中逻辑非常复杂,本文主要只概要描述不同回收场景下内核设计的主要思想,源码细节不同版本有不少区别,具体的分析后续会有专门的文章分析。

 页面回收常识:

  • 页面扫描回收时才意味着老化。
    • 一个页面被访问之后,相应的access标记会一直打在那里,直到这个页面被扫描。LRU里面的时间流逝跟自然时间是没有关系的,扫描才是推动历史车轮前进的动力。而扫描又是由于达不到balanced而被触发的,可见页面老化的速度跟系统中内存的紧缺程度是相关的。内存紧缺的时候,1分钟前才被访问过的页面可能都不会被视作活跃;反过来,如果内存不紧缺,长期不需要进行回收,那么几小时前访问过的页面又可能都会被视作活跃,并且在这段时间内被访问过一次和被访问过多次的页面会被同等对待(access是标记而不是计数);
 kswapd后台异步回收

1)何时唤起kswapd:

  • 如果内存低于low watermark系统会唤醒kswapd进行内存回收
  • alloc_page申请内存时候,先使用low watermark进行快速内存申请,如果失败了就会进入慢路径(也就是说free page < low),这个时候会主动wakeup kswapd,同时使用min watermark申请内存。

2)kswapd何时停止,回收(一个for循环)的频率如何

     核心思路:既要高效回收page,又不能过度消耗CPU。

  • 如上图kswapd如果判定pgdat_balanced(判定order和high watermark是否满足),那么就先进入“浅睡眠”(schdule_timeout(100)),避免马上陷入full sleep(TASK_INTERRUPTIBLE sleep),只能等到direct reclaim唤醒了,影响了内存分配性能,这里也可以看出kswapd的作用就是要尽量保持内存在high watermark,但是又要避免for(;;)过度循环导致cpu太高。
  • 如果kswapd回收后满足pgdat_balanced陷入睡眠后,将wakeup_kcompactd,做内存compact。
  • 如果kswapd一直回收而始终不满足pgdat_balanced,那么kswapd prepare_kswapd_sleep返回false,意味者kswapd不能休息要一直回收

3)kswapd 回收page目标数量是多少?

  • 目标:free page要满足high watermark;而kswapd又是从低于low watermark开始回收的,故源码设置sc.nr_to_reclaim尽量比较大能满足上述目标,如下:
	for (z = 0; z <= sc->reclaim_idx; z++) {
		zone = pgdat->node_zones + z;
		if (!managed_zone(zone))
			continue;
        //high_wmark_pages返回的high watermark值
		sc->nr_to_reclaim += max(high_wmark_pages(zone), SWAP_CLUSTER_MAX);
	}

 注意虽然kswapd的sc.nr_to_reclaim虽然设置的回收目标挺大的,但是真正执行shrink回收页面的时候(实际上指shrink_list)一次回收的单位最大是SWAP_CLUSTER_MAX(32)个pages。

4)kswapd回收的方向(zone)和 order?

  • kswapd回收方向和alloc_pages方向相关尽力避免锁竞争。
    • alloc_pages方向是从high zone-> low zone;kswapd反之
  • kswapd会从alloc_pages拿到目标zone(prefered zone)和order,然后按zone 0 -> prefered zone顺序回收(比如prefered zone是1,那么只回收0 - 1zone,不要浪费时间去收回zone 2)
  • 上面大概提到判定zone是否平衡的条件有考虑order,可参见源码pgdat_balanced函数,平衡不仅仅是要free pages > high watermark,同时至少要有2^order连续的物理内存才可。

5)kswapd's scan control priority优先级设置

  • kswapd开始以DEF_PRIORITY(12)的优先级开始扫描
  • 调用函数balance_pgdat在do{}循环中进行回收,如果一轮循环回收后没有balance,那就不断将priority提升,增加一轮scan page数量;如果priority最高后还没有balance,根据watermark_boots情况可以看是否wakeup_kcompactd。

direct reclaim
  • 快速路径申请:
    • 以ALLOC_WMARK_LOW申请内存,zone水位不满足条件(即free pages < low),node_reclaim触发回收,此过程不能够引入I/O开销,因此不能对mapped anonymous page或者脏文件页回写操作,主要针对的是unmapped file pages和 slab pages,上述类型的内存页可直接被回收:
static int __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
{
    ...
	struct scan_control sc = {
		.nr_to_reclaim = max(nr_pages, SWAP_CLUSTER_MAX),
		.gfp_mask = current_gfp_context(gfp_mask),
		.order = order,
		.priority = NODE_RECLAIM_PRIORITY,
		.may_writepage = !!(node_reclaim_mode & RECLAIM_WRITE),
		.may_unmap = !!(node_reclaim_mode & RECLAIM_UNMAP),
		.may_swap = 1,
		.reclaim_idx = gfp_zone(gfp_mask),
	};
    ...
}

my_writepage = 0:代表不能进行页面回写落盘

my_unmap = 0 : 不能进行try_to_unmap(page)等unmap解除页表映射。

may_swap = 1;可以进行页面swap操作,android上比如可以机型zram匿名页压缩。

priority : 回收优先级是4,即最多尝试调用shrink_node进行回收的次数为4次,或者当回收到的页数达到需要分配的内存页数停止。

nr_to_reclaim:请求分配页面和SWAP_CLUSTER_MAX的最大值,即最少也要扫描32个page,否则一次shrink性价比太低了。

慢路径申请:

如果快速路径回收页面后依旧分配内存失败,则会进入到慢速分配路径,慢速分配会尝试从所有zone中以WMARK_MIN阀值分配内存页。在慢速分配路径中,会再次尝试快速路径回收,未成功则调用__alloc_pages_direct_reclaim进行内存回收。允许mapped anonymous page回收,且如果laptop_mode不为真,则允许脏文件页写回。laptop_mode通过/proc/sys/vm/laptop_mode控制,为0允许直接内存回收对脏页进行回写操作。try_to_free_pages每次回收页面最大值为32(SWAP_CLUSTER_MAX),priority为12,shrink_node最多会被调用12次。

unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
                gfp_t gfp_mask, nodemask_t *nodemask)
{
    unsigned long nr_reclaimed;
    struct scan_control sc = {
        .nr_to_reclaim = SWAP_CLUSTER_MAX,
        .gfp_mask = current_gfp_context(gfp_mask),
        .reclaim_idx = gfp_zone(gfp_mask),
        .order = order,
        .nodemask = nodemask,
        .priority = DEF_PRIORITY,
        .may_writepage = !laptop_mode,
        .may_unmap = 1,
        .may_swap = 1,
    };

调用栈:

#0  shrink_node (pgdat=0xffff888007fda000, sc=0xffff888005767450) at mm/vmscan.c:2672
#1  0xffffffff81356a4a in shrink_zones (sc=<optimized out>, zonelist=<optimized out>) at mm/vmscan.c:2971
#2  do_try_to_free_pages (zonelist=<optimized out>, sc=0xffff888005767450) at mm/vmscan.c:3026
#3  0xffffffff81358cec in try_to_free_pages (zonelist=0xffff888007fdb400, order=0, gfp_mask=<optimized out>, nodemask=<optimized out>) at mm/vmscan.c:3265
#4  0xffffffff813bcd27 in __perform_reclaim (ac=<optimized out>, ac=<optimized out>, order=<optimized out>, gfp_mask=<optimized out>) at mm/page_alloc.c:4274
#5  __alloc_pages_direct_reclaim (did_some_progress=<optimized out>, ac=<optimized out>, alloc_flags=<optimized out>, order=<optimized out>, gfp_mask=<optimized out>) at mm/page_alloc.c:4295
#6  __alloc_pages_slowpath (gfp_mask=<optimized out>, order=<optimized out>, ac=0x0 <fixed_percpu_data>) at mm/page_alloc.c:4699
#7  0xffffffff813bdf9d in __alloc_pages_nodemask (gfp_mask=1125578, order=0, preferred_nid=<optimized out>, nodemask=<optimized out>) at mm/page_alloc.c:4915
#8  0xffffffff813e0637 in alloc_pages_current (gfp=1125578, order=0) at ./include/linux/topology.h:88
#9  0xffffffff8132b0b5 in alloc_pages (order=<optimized out>, gfp_mask=<optimized out>) at ./include/linux/gfp.h:545
#10 __page_cache_alloc (gfp=<optimized out>) at mm/filemap.c:957
#11 __page_cache_alloc (gfp=1125578) at mm/filemap.c:942

具体回收的过程以及判定哪些页面怎么处理的细节后面文章分析。

思考问题:

        现在内核如果kswapd回收,但是一直无法balance,没有措施确保kswapd能歇一歇?会不会造成cpu浪费?

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

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

相关文章

【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中&#xff0c;有一个很常用的数据结构&#xff0c;那就是切片&#xff08;Slice&#xff09;。 切片是一个拥有相同类型元素的可变长度的序列&#xff0c;它是基于数组类型做的一层封装…

【LeetCode】二叉树的前序,中序,后序遍历

此题用递归做比较容易&#xff0c;然后根据前中后的遍历特点&#xff1a; 前序是根左右&#xff0c; 中序是左根右&#xff0c; 后序是左右根。 前序遍历&#xff1a;做题入口 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer…

IntersectionObserver实现小程序长列表优化

IntersectionObserver实现小程序长列表优化 关于 IntersectionObserver 思路 这里以一屏数据为单位【一个分页的10条数据&#xff0c;最好大于视口高度】&#xff0c; 监听每一屏数据和视口的相交比例&#xff0c;即用户能不能看到它 只将可视范围的数据渲染到页面上&#x…

2025年卡脖子技术清零?甚至计划推动鸿蒙欧拉比肩全球领先水平

深圳市工业和信息化局近日发布了推动开源鸿蒙欧拉产业创新发展的行动计划&#xff0c;以推动鸿蒙欧拉在2023至2025年期间成为全球领先操作系统&#xff0c;并构建全球信息技术体系&#xff0c;实现我国操作系统技术创新和自主发展目标。 该计划旨在加强操作系统技术能力&#x…

造个轮子--用Python写个语法解析器

文章目录 前言选型针对人群目标技术实现本文目标 效果实现字符指针错误类型语法解析交互 前言 目的纯粹&#xff0c;基于Python做一个简单的新的简单的编程语言。一方面是开拓视野&#xff0c;另一方面是作为毕设的临时过渡方案&#xff08;没错&#xff0c;先前提到的算法平台…

抖音短视频矩阵系统源码:SEO优化开发解析

抖音短视频矩阵系统源码是一个基于抖音短视频平台的应用程序。它允许用户上传和观看短视频&#xff0c;以及与其他用户交互。SEO优化开发解析是指对该系统进行搜索引擎优化的开发解析。 一、 在进行SEO优化开发解析时&#xff0c;可以考虑以下几点&#xff1a; 关键词优化&…

【Python数据分析】Python常用内置函数(一)

&#x1f389;欢迎来到Python专栏~Python常用内置函数&#xff08;一&#xff09; ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文…

在撰写公文时,要注意使用正确的格式和样式

在撰写公文时&#xff0c;注意使用正确的格式和样式&#xff0c;以符合公文的规范要求是非常重要的。 公文是一种正式文书&#xff0c;需要遵循一定的格式和样式要求&#xff0c;以符合公文的规范和标准。在撰写公文时&#xff0c;需要注意以下几点&#xff1a; 1.文字排版&…

day46-Quiz App(测试题计分)

50 天学习 50 个项目 - HTMLCSS and JavaScript day46-Quiz App&#xff08;测试题计分&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" conte…

【matlab】机器人工具箱快速上手-动力学仿真(代码直接复制可用)

动力学代码&#xff0c;按需修改参数 各关节力矩-关节变量的关系曲线&#xff1a; %%%%%%%%SCARA机器人仿真模型 l[0.457 0.325]; L(1) Link(d,0,a,l(1),alpha,0,standard,qlim,[-130 130]*pi/180);%连杆1 L(2)Link(d,0,a,l(2),alpha,pi,standard,qlim,[-145 145]*pi/180);%连…

代理模式--静态代理和动态代理

1.代理模式 定义&#xff1a;代理模式就是代替对象具备真实对象的功能&#xff0c;并代替真实对象完成相应的操作并且在不改变真实对象源代码的情况下扩展其功能&#xff0c;在某些情况下&#xff0c;⼀个对象不适合或者不能直接引⽤另⼀个对象&#xff0c;⽽代理对象可以在客户…

华为OD机试真题 Java 实现【最长公共后缀】【2023 B卷 100分】,等于白送

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明4、再输入5、再输出 七、机考攻略 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff…

【Golang】Golang进阶系列教程--Go 语言数组和切片的区别

文章目录 前言数组声明以及初始化函数参数 切片声明以及初始化函数参数 总结 前言 在 Go 语言中&#xff0c;数组和切片看起来很像&#xff0c;但其实它们又有很多的不同之处&#xff0c;这篇文章就来说说它们到底有哪些不同。 数组和切片是两个常用的数据结构。它们都可以用…

LBERT论文详解

论文地址&#xff1a;https://arxiv.org/abs/2105.07148 代码地址&#xff1a;https://github.com/liuwei1206/LEBERT 模型创新 LEBRT采用句子中的词语对&#xff08;论文中称为Char-Word Pair&#xff09;的特征作为输入作者设计Lexicon adapter&#xff0c;在BERT的中间某一…

Codeforces Round 839 (Div. 3)E题解

文章目录 [Permutation Game](https://codeforces.com/contest/1772/problem/E)问题建模问题分析1.分析一个玩家想要获胜的关键2.分析阻塞元素的类别3.分析阻塞元素的类别对于局面的影响代码 Permutation Game 问题建模 给定一个长度为n的排列&#xff0c;排列的每个元素都被阻…

CentOS 7安装PostgreSQL 15版本数据库

目录 一、何为PostgreSQL&#xff1f; 二、PostgreSQL安装 2.1安装依赖 2.2 执行安装 2.3 数据库初始化 2.4 配置环境变量 2.5 创建数据库 2.6 配置远程 2.7 测试远程 三、常用命令 四、用户创建和数据库权限 一、何为PostgreSQL&#xff1f; PostgreSQL是以加州大学…

DGNN Survey

Dynamic Graph Definition G ( V , E , X ) G (V, E, X) G(V,E,X) V v 1 , v 2 , . . . , v m V {v_1, v_2, ..., v_m} Vv1​,v2​,...,vm​ E e i , j E {e_{i, j}} Eei,j​ , e i , j ( v i , v j , f i , j ) e_{i,j} (v_i, v_j, f_{i,j}) ei,j​(vi​,vj​,fi,j​…

M1/M2 通过VM Fusion安装Win11 ARM,解决联网和文件传输

前言 最近新入了Macmini M2&#xff0c;但是以前的老电脑的虚拟机运行不起来了。&#x1f605;&#xff0c;实际上用过K8S的时候&#xff0c;会发现部分镜像也跑不起来&#xff0c;X86的架构和ARM实际上还是有很多隐形兼容问题。所以只能重新安装ARM Win11&#xff0c;幸好微软…

【初阶C语言】整数比大小

各位大佬的光临已是上上签 在C语言刷题过程中&#xff0c;一定遇到过很多比大小的题目&#xff0c;那么本节就专门介绍比大小的方法&#xff0c;若大佬们还有更优解&#xff0c;欢迎补充呀&#xff01; 本节讲解的方法主要有三种&#xff1a;1.条件判断 2.三目操作符 3.函数调…

JA64 1+2+3+...n

一、题目 求123...n_牛客题霸_牛客网 二、代码 1.使用静态成员变量构造函数 class SUM {private:static int _i;static int _ret;public:SUM(){_ret _ret _i;_i;}static int GetRet(){return _ret;} }; int SUM::_i1; int SUM::_ret0;class Solution { public:int Sum_So…