专题:Linux内存管理专题

关键词:匿名页面、换入、换出。

如果要将匿名页面的生命周期进行划分,大概就是诞生、使用、换出、换入和销毁。

内核中使用匿名页面的地方有很多,产生缺页中断之后匿名页面就诞生了;

用户进程访问虚拟地址即可访问到匿名页面内容;

在内存紧张的时候,需要回收一些页面来释放内存,匿名页面可能被换出;

如果虚拟地址空间被再次访问,则需要将swap分区中内容换入;

当进程关闭或者退出时,VMA上的映射需要被清除,相关匿名页面会被销毁。

1. 匿名页面的诞生

从内核的角度看,出现匿名页面的情况有:

1. 用户空间malloc/mmap接口函数来分配内存,在内核空间发生缺页中断时,调用do_anonymous_page()会产生匿名页面。

2. 发生写时复制,当缺页中断出现写保护错误时,新分配的页面是匿名页面。

2.1 do_wp_page(),只读的special映射的页面,例如映射到zeroed的页面;非单身匿名页面;只读的私有映射的page cache;KSM页面。

2.2 do_cow_page(),共享的匿名页面(shared anonymous mapping, shmm)

3. do_swap_page(),从swap分区 读回数据时会新分配匿名页面。

4. 迁移页面

2. 匿名页面的使用

匿名页面在缺页中断中分配完成之后,就建立了进程虚拟地址空间VMA和物理页面的映射关系,用户进程访问虚拟地址即访问到匿名页面的内容。

3. 匿名页面的换出

假设系统内存紧张,需要回收一些页面来释放内存。

anon_page刚分配时会加入活跃LRU链表(LRU_ACTIVE_ANON)头部,在经历了活跃LRU链表的一段时间的移动,

该anon_page到达活跃LRU链表的尾部,shrink_active_list()函数把该页加入不活跃LRU链表(LRU_INACTIVE_LRU)。

shrink_inactive_list()函数扫描不活跃链表,shrink_page_list()回首页面。

(1) 第一次扫描不活跃链表时,shrink_page_list()->add_to_swap()函数会为该页分配swap分区空间

此时匿名页面的_count、_mapcount、flags状态如下:

page->_count = 3(引用计数增加的地方:1-分配页面;2-分离页面;3-add_to_swap())

page->_mapcount = 0

page->flags = PG_lru | PG_swapbacked PG_swapcache | PG_dirty | PG_uptedate | PG_locked,

PG_swapcache表示该页已经分配了swap空间,PG_dirty表示该页为脏,稍后需要写回swap分区,PG_uptodate表示该也得数据是有效的。

(2) shrink_page_list()->try_to_unmap()后该匿名页面状态如下

page->_count = 2

page->_mapcount = -1---------表示没有PTE映射该页

try_to_unmap()会通过RMAP反响映射系统去寻找映射该页的所有VMA和相应的PTE,并将这些PTE解除映射。

因为该页只和父进程建立了映射关系,因此_count和_mapcount都要减1。

(3) shrink_page_list()->pageout()函数把该页写回交换分区,此时匿名页面状态如下

page->_count = 2

page->_mapcount = -1

page->flags = PG_lru | PG_swapbacked | PG_swapcache | PG_dirty | PG_uptedate | PG_reclaim | PG_writeback

(4) 第二次扫描不活跃链表

经历第一次不活跃LRU链表的移动过程,从链表头移动到链表尾。

如果这时该页还没有写入完成,即PG_writeback标志位还在,那么该页会继续被放回到不活跃LRU链表头,kswapd会继续扫描其它页,从而继续等待写完成。

假设第二次扫描不活跃链表时,该页写入swap分区已经完成。Block Layer层毁掉函数end_swap_bio_write()->end_page_writeback()完成如下动作:

  • 清PG_writeback标志位
  • 唤醒等待在该页PG_writeback的线程,见wake_up_page(page, PG_writeback)函数。

shrink_page_list()->__remove_mapping()执行后如下:

page->_count = 0

page->_mapcount = -1

page->flags = PG_swapbacked | PG_uptedate

最后把page加入free_page链表中,释放该页。因此该anon_page页的状态是页面内容已经写入swap分区,实际物理页面已经释放。

4. 匿名页面的换入

匿名页面被换出到swap分区后,如果应用程序需要读写这个页面,缺页中断发生。

因为pte中的L_PTE_PRESENT比特位显示该物理页面不在内存中,但PTE表项不为空,说明该页被交换到swap分区去了,因此调用do_swap_page()函数重新读入该页的内容。

5. 匿名页面销毁

当用户进程关闭或者退出时,会扫描这个用户进程所有的VMAs,并会清除这些VMA上所有的映射,如果符合这些标准,相关页面会被释放。

Linux内存管理 (14)匿名页面生命周期的更多相关文章

  1. Linux内存管理 (13)回收页面

    专题:Linux内存管理专题 关键词:LRU.活跃/不活跃-文件缓存/匿名页面.Refault Distance. 页面回收.或者回收页面也即page reclaim,依赖于LRU链表对页面进行分类: ...

  2. JVM的内存管理、对象的生命周期、内存泄漏

    1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...

  3. cocos2d内存管理,类的生命周期

    下面资料来自<Cocos2d-x之Lua核心编程>

  4. Linux内存管理专题

    Linux的内存管理涉及到的内容非常庞杂,而且与内核的方方面面耦合在一起,想要理解透彻非常困难. 在开始学习之前进行了一些准备工作<如何展开Linux Memory Management学习?& ...

  5. Linux内存管理 (15)页面迁移

    专题:Linux内存管理专题 关键词:RMAP.页面迁移. 相关章节:反向映射RMAP.内存规整. 页面迁移的初衷是为NUMA系统提供一种将进程迁移到任意内存节点的能力,后来内存规整和内存热插拔场景都 ...

  6. Linux内存描述之内存页面page–Linux内存管理(四)

    服务器体系与共享存储器架构 日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDriver ...

  7. WebApp中的页面生命周期及路由管理

    最近切换到一个新项目,使用的技术栈是Require+Backbone,鉴于对鞋厂webapp框架的了解,发现这个新项目有些缺陷,主要是单纯依赖Backbone造成的,也就是Backbone的好和坏都在 ...

  8. Linux内存管理 (4)分配物理页面

    专题:Linux内存管理专题 关键词:分配掩码.伙伴系统.水位(watermark).空闲伙伴块合并. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行. 从Linux内存 ...

  9. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

随机推荐

  1. 图像检索(1): 再论SIFT-基于vlfeat实现

    概述 基于内容的图像检索技术是采用某种算法来提取图像中的特征,并将特征存储起来,组成图像特征数据库.当需要检索图像时,采用相同的特征提取技术提取出待检索图像的特征,并根据某种相似性准则计算得到特征数据 ...

  2. 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(6)- 打包发布(PyInstaller3.3.1)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之打包发布. 经过上一篇软件优化之后,Jays-PyCOM已经初长成,该到了出去历练的时候了,只有经 ...

  3. 内存管理-MRC与ARC详解

    Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提 ...

  4. GUID获取16位19位22位的唯一字符串

    /// <summary> /// 根据GUID获取16位的唯一字符串 /// </summary> /// <param name=\"guid\" ...

  5. VSTO中Word转换Range为Image的方法

    VSTO中Word转换Range为Image的方法 前言 VSTO是一套用于创建自定义Office应用程序的Visual Studio工具包,通过Interop提供的增强Office对象,可以对Wor ...

  6. Spring笔记01_下载_概述_监听器

    目录 Spring笔记01 1.Spring介绍 1.1 Spring概述 1.2 Spring好处 1.3 Spring结构体系 1.4 在项目中的架构 1.5 程序的耦合和解耦 2. Spring ...

  7. 零基础学Python--------第5章 字符串及正则表达式

    第5章 字符串及正则表达式 5.1 字符串常用操作 在Python开发过程中,为了实现某项功能,经常需要对某些字符串进行特殊处理,如拼接字符串.截取字符串.格式化字符串等.下面将对Python中常用的 ...

  8. css transition 实现滑入滑出

    transition是css最简单的动画. 通常当一个div属性变化时,我们会立即看的变化,从旧样式到新样式是一瞬间的,嗖嗖嗖!!! 但是,如果我希望是慢慢的从一种状态,转变成另外一种状态,怎么办?  ...

  9. 解决一个Ubuntu中编译NEON优化的OpenCV的错误

    在Ubuntu 16中编译开启NEON优化的Opencv时,遇到libpng编译是使用汇编代码的错误,完整错误见文章末尾.通过查询发现解决方案是安装跨平台编译器,安装代码如下: sudo apt-ge ...

  10. 如何正确使用Espresso来测试你的Android程序

    UI测试在Android平台上一直都是一个令人头痛的事情, 由于大家平时用的很少, 加之很多文档的缺失, 如果很多东西从头摸索,势必踩坑无数. 自Android24正式淘汰掉了Instrumentat ...