欢迎来到五大联赛竞猜

产品中心 一文望懂内存交换机制

正文:

本文基于 Linux-2.4.16 内核版本

【那个叫做罗纳尔多的天才】

西班牙首相佩德罗-桑切斯确认,西甲西乙将在6月8日的那一周重启。而西甲主席特巴斯将在未来几天公布正式的复赛时间。

纵观足坛风云变幻,笑谈绿茵关键事件。绝杀与误判,出局与晋级,荣誉与失落,作为一名“”,你如何看待足坛风云?

目前国安的主场工体正处于改造阶段产品中心,《北京晚报》8月27日上午实地探访施工现场,拿到了复建后新工体的内部设计方案。

由于计算机的物理内存是有限的, 而进程对内存的行使是不确定的, 以是物理内存总有用完的能够性. 那么当编制的物理内存不及时, Linux内核行使什么方案来避免申请不到物理内存这个题目呢?

相对于内存来说, 磁盘的容量是专门大的, 以是Linux内核实现了一个叫 内存交换 的功能 -- 把某些进程的一些一时用不到的内存页保存到磁盘中, 然后把物理内存页分配给更危险的用户行使, 当进程用到时再从磁盘读回到内存中即可. 有了 内存交换 功能, 编制可行使的内存就能够远广大于物理内存的容量。

LRU算法

内存交换 过程最先是找到一个正当的用户进程内存管理组织,然后把进程占用的内存页交换到磁盘中,并断开虚拟内存与物理内存的映射,末了开释进程占用的内存页。由于涉及到IO操作,以是这是一个比较耗时的过程。倘若被交换出往的内存页刚益又被访问了,这时又必要从磁盘中把内存页的数据交换到内存中。以是,在这栽情况下不光不克解决内存紧缺的题目,而且增补了编制的负荷。

为晓畅决这个题目,Linux内核行使了一栽称为 LRU (Least Recently Used) 的算法, 下面介绍一下 LRU算法 的大体过程。

LRU 的中文翻译是 比来最少行使, 顾名思义就是一段时间内异国被行使, 那么Linux内核怎么清新哪些内存页面比来异国被行使呢? 最浅易的手段就是把内存页放进一个队列里, 倘若内存页被访问了, 就把内存页移动到链外的头部, 如许没被访问的内存页在一段时间后便会移动到队列的尾部, 而开释内存页时从链外的尾部开起. 著名的缓存服务器 memcached 就是行使这栽 LRU算法。

Linux内核也行使了相通的算法, 但相对要复杂一些. Linux内核维护着三个队列: 活跃队列, 非活跃脏队列和非活跃清洁队列. 为什么Linux必要维护三个队列, 而不是行使一个队列呢? 这是由于Linux期待内存页交换过程徐徐进走, Linux内核有个内核线程 kswapd 会准时检查编制的余暇内存页是否紧缺, 倘若编制的余暇内存页紧缺往往, 就会选择一些用户进程把其占用的内存页增补到活跃链外中并断开进程与此内存页的映射有关. 随着时间的推移, 倘若内存页异国被访问, 那么就会被移动到非活跃脏链外. 非活跃脏链外中的内存页是必要被交换到磁盘的, 当编制中余暇内存页紧缺时就会从非活跃脏链外的尾部开起把内存页刷新到磁盘中, 然后移动到非活跃清洁链外中, 非活跃清洁链外中的内存页是能够立刻分配给进程行使的. 各个链外之间的移动如下图:

lru links

倘若在这个过程中, 内存页又被访问了, 那么Linux内核会把内存页移动到活跃链外中, 并且竖立内存映射有关, 如许就不必要从磁盘中读取内存页的内容。

仔细: 内核只维护着一个活跃链外和一个非活跃脏链外, 但是非活跃清洁链外是每个内存管理区都有一个的。

这是由于分配内存是在内存管理区的基础上进走的, 以是一个内存页必须属于某一个内存管理区。

kswapd内核线程

在Linux编制启动时会调用 kswapd_init() 函数, 代码如下:

static int __init kswapd_init(void) {     printk("Starting kswapd v1.8\n");     swap_setup();     kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);     kernel_thread(kreclaimd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);     return 0; } 

能够望到产品中心, kswapd_init() 函数会创建 kswapd 和 kreclaimd 两个内核线程, 这两个内核线程负责在编制物理内存紧缺时开释一些物理内存页, 从而使编制的可用内存达到一个均衡. 下面吾们重点来分析 kswapd 这个内核线程, kswapd() 的源码如下:

int kswapd(void *unused) {     struct task_struct *tsk = current;      tsk->session = 1;     tsk->pgrp = 1;     strcpy(tsk->comm, "kswapd");     sigfillset(&tsk->blocked);     kswapd_task = tsk;      tsk->flags |= PF_MEMALLOC;      for (;;) {         static int recalc = 0;          if (inactive_shortage() 
			
posted @ 21-09-05 02:10  作者:admin  阅读量:

Powered by 五大联赛竞猜 @2018 RSS地图 HTML地图