内存回收

内核主要有4种LRU链表:

enum lru_list {

LRU_INACTIVE_ANON = LRU_BASE,

LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE,

LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE,

LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE,

LRU_UNEVICTABLE,

NR_LRU_LISTS

};

inactive_anon - # anonymous and swap cache memory on inactive LRU list.

active_anon - #anonymous and swap cache memory on active LRU list.

inactive_file - # file-backed memory on inactive LRU list.

active_file - # file-backed memory on active LRU list.

内核回收内存时,会在get_scan_out中计算每个链表中回收的page数量:

/*

 * Determine how aggressively the anon and file LRU lists should be

 * scanned.  The relative value of each set of LRU lists is determined

 * by looking at the fraction of the pages scanned we did rotate back

 * onto the active list instead of evict.

 *

 * nr[0] = anon inactive pages to scan; nr[1] = anon active pages to scan

 * nr[2] = file inactive pages to scan; nr[3] = file active pages to scan

 */

static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,

unsigned long *nr)

** (1)如果没有swap space,就不会回收anonymous page: **

/* If we have no swap space, do not bother scanning anon pages. */

if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {

scan_balance = SCAN_FILE;

goto out;

}

** (2)如果是group回收,且memory.swappiness==0,则回收file cache: **

/*

* Global reclaim will swap to prevent OOM even with no

* swappiness, but memcg users want to use this knob to

* disable swapping for individual groups completely when

* using the memory controller‘s swap limit feature would be

* too expensive.

*/

if (!global_reclaim(sc) && !vmscan_swappiness(sc)) {

scan_balance = SCAN_FILE; ///mem cgroup swappiness == 0

goto out;

}

** (3)系统(group)内存已经不足,且swappiness!=0,则anon page和file cache都可以回收: **

/*

* Do not apply any pressure balancing cleverness when the

* system is close to OOM, scan both anon and file equally

* (unless the swappiness setting disagrees with swapping).

*/

if (!sc->priority && vmscan_swappiness(sc)) {

scan_balance = SCAN_EQUAL;

goto out;

}

** (4)如果空闲页(free)+file cache小于high water mark,则回收anon page(注:仅对全局回收): **

anon  = get_lru_size(lruvec, LRU_ACTIVE_ANON) +

get_lru_size(lruvec, LRU_INACTIVE_ANON);

file  = get_lru_size(lruvec, LRU_ACTIVE_FILE) +

get_lru_size(lruvec, LRU_INACTIVE_FILE);

/*

* If it‘s foreseeable that reclaiming the file cache won‘t be

* enough to get the zone back into a desirable shape, we have

* to swap.  Better start now and leave the - probably heavily

* thrashing - remaining file pages alone.

*/

if (global_reclaim(sc)) {

free = zone_page_state(zone, NR_FREE_PAGES);

if (unlikely(file + free <= high_wmark_pages(zone))) {

scan_balance = SCAN_ANON;

goto out;

}///file cache isn‘t enough, add ANON

}

** (5)inactive file cache足够,则回收file cache: **

/*

* There is enough inactive page cache, do not reclaim

* anything from the anonymous working set right now.

*/

if (!inactive_file_is_low(lruvec)) {

scan_balance = SCAN_FILE;

goto out;

}

** (6)其它情况,则根据swappiness计算回收anon page和file cache page的数量: **

scan_balance = SCAN_FRACT;

/*

* With swappiness at 100, anonymous and file have the same priority.

* This scanning priority is essentially the inverse of IO cost.

*/

anon_prio = vmscan_swappiness(sc);

file_prio = 200 - anon_prio;

时间: 2024-10-11 07:18:47

内存回收的相关文章

(转)从内存管 理、内存泄漏、内存回收探讨C++内存管理

http://www.cr173.com/html/18898_all.html 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对 C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过的,除非放弃 C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能

关于jvm内存回收问题

目前内存的动态分配与内存回收技术已经相当成熟,那为什么我们还要去了解GC和内存分配呢?答案很简单:当需要排查各种内存溢出,内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调节. 有三部分内存区域:程序计数器,虚拟机栈,本地方法栈,它们随线程而生,随线程而灭.栈中的栈帧随着方法的进入和退出而有条不紊的进行着岀栈和如栈操作.每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就

Android内存回收机制

退出但不关闭: 这是Android对于Linux的优化.当 Android 应用程序退出时,并不清理其所占用的内存,Linux 内核进程也相应的继续存在,所谓“退出但不关闭”.从而使得用户调用程序时能够在第一时间得到响应. 应用切换到后台是暂停的,完全不耗cpu和电量,只保留了运行状态.如果app需要后台处理事务(放音乐),那么app进程会开启相应的服务,所以在后台有消耗的只有服务. 占用CPU的应用才耗电,后台的只占内存,所以是不耗电的.默认回收机制: 当系统内存不足时,系统将激活内存回收过程

js 作用域链&amp;内存回收&amp;变量&amp;闭包

闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等 一.作用域链:函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内部的规则是,把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止.当函数中需要查询一个变量的值的时候,js解释器会去作用域链去查找,从最前面的本地变量中先找,如果没有找到对应的变量,则到下一级的链上找,一旦找到了变量,则不再继续.如果找到最后也没找到需要的变量,则

并行编程中的内存回收Hazard Pointer

接上篇使用RCU技术实现读写线程无锁,在没有GC机制的语言中,要实现Lock free的算法,就免不了要自己处理内存回收的问题. Hazard Pointer是另一种处理这个问题的算法,而且相比起来不但简单,功能也很强大.锁无关的数据结构与Hazard指针中讲得很好,Wikipedia Hazard pointer也描述得比较清楚,所以我这里就不讲那么细了. 一个简单的实现可以参考我的github haz_ptr.c 原理 基本原理无非也是读线程对指针进行标识,指针(指向的内存)要释放时都会缓存

(转)PHP zval内存回收机制和refcount_gc和is_ref_gc

出处 : http://blog.sina.com.cn/s/blog_75a2f94f0101gygh.html 对于PHP这种需要同时处理多个请求的程序来说,申请和释放内存的时候应该慎之又慎,一不小心便会酿成大错.另一方面,除了要安全的申请和释放内存外,还应该做到内存的最小化使用,因为它可能要处理每秒钟数以千计的请求,为了提高系统整体的性能,每一次操作都应该只使用最少的内存,对于不必要的相同数据的复制则应该能免则免.我们来看下面这段PHP代码: $a = "hello"; $b =

第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 方法区:回收两样东西 无用的类 废弃的常量 栈和PC寄存器是线程私有区域,不发生GC 2.怎样判断对象是否存活 垃圾回收:回收掉死亡对象所占的内存.判断对象是否死亡,有两种方式: 引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值+1:引用失效时,计数器值-1 实际中不用,不用的两

JVM方法区内存回收

很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区进行垃圾收集的"性价比"一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~95%的空间,而永久代的垃圾收集效率远低于此. 永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类. 先来说说方法区内常量池之中主要存放的两大类常量:字面量和符号引用.字面量比较接近Java语言层次的常量概念,如文本字符串.被声明

内存回收,Dispose,Close,Finalie(C#中的析构函数)

NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收. 也就是大家熟知的GC(垃圾回收机制). 而对于 非托管资源,比如数据库连接,COM连接等,那么需要手动清理回收资源. 清理非托管资源,我们可以用析构函数来执行,虽然它的执行时机不确定,但终究会被执行. 当然还有Dispose()和Close()方法,两者的区别在于,Close()后还要以用Open()打开,而Dispose()则是彻底销毁.--- 使用析构函数时,需要GC.Co

RHCA442学习笔记-Unit11内存回收

Unit 12 Memory Reclamation 内存回收            学习目标: A. 了解和调整内存回收 B.   调整内存溢出 C. 调整虚拟内存(swap)的使用 12.1        Characterizing page status各种页面状态的特征 A. .Free 空闲页 页面可以马上分配给进程 B Inactive Clean 干净页 a. 页面内容已写入磁盘,或者 b. 数据从磁盘读入内存后未作修改 c. 这种页面可以分配 C. Inactive Dirty