安卓内核内存回收

背景

  一般上层由于业务需要,需要内核提供一些定制的内存回收接口。或者内核层本来就想做内存机制的优化。便需要在原有内存回收机制上做一些hook操作。所以了解Linux内核内存回收流程很重要
  本章节主要讲kswapd线程,当内存低watermark时,kswapd会被唤醒并开始工作。

kswapd架构简介

  在numa架构下,内核将内存划分为多个node,每个node划分为多个zone,每个zone划分成多个page。node作为一个管理节点,与之对应的有多个cpu核心。同时每个node都会创建一个kswapd线程,这个线程负责管理节点内所有zone的页面。

内存回收步骤

  1. kswapd初始化
    1、设置每次swap的page数
    2、创建kswapd线程,多个numa节点对应多个线程。
  2. 执行kswapd()
    1、进入for死循环
    2、整理内存碎片后,进入睡眠。
    3、被唤醒后,执行回收

内存回收详细步骤

  1. kswapd初始化
static int __init kswapd_init(void) {
   
	swap_setup();//设置page_cluster,作用是确定每次swap in/out多少page(2^page_cluster)
	for_each_node_state(nid, N_MEMORY)//遍历所有numa节点
 		kswapd_run(nid);//为每个numa节点创建kswapd线程
}
void kswapd_run(int nid) {
    //为每个节点id 创建kswapd线程
	pgdat->kswapd = kthread_run(kswapd, pgdat, "kswapd%d", nid);
}
mm/vmscan.c
  1. 执行kswapd()
// kswapd整个生命都在这儿
static int kswapd(void *p) {
   
	pg_data_t *pgdat = (pg_data_t *)p; //每个numa节点,通过pg_data_t描述物理内存布局
	for ( ; ; ) {
   
		//判断kswapd是否进入睡眠,并让出cpu。
		kswapd_try_to_sleep(pgdat, alloc_order, reclaim_order, highest_zoneidx);
		// 回收page
		reclaim_order = balance_pgdat(pgdat, alloc_order, highest_zoneidx);
	}
}
// 尝试睡眠
static void kswapd_try_to_sleep(pg_data_t *pgdat, int alloc_order, int reclaim_order, unsigned int highest_zoneidx) {
   
	//将kswapd线程加入此内存节点的wait队列
	prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
	//小睡一会,目的是唤醒 内存压缩线程,整理内存碎片
	if (prepare_kswapd_sleep(pgdat, reclaim_order, highest_zoneidx)) {
   
		wakeup_kcompactd(pgdat, alloc_order, highest_zoneidx);//唤醒内存压缩线程
		remaining = schedule_timeout(HZ/10);//小睡一会
		finish_wait(&pgdat->kswapd_wait, &wait);
		prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
	}
	if 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值