linux内存管理2:内存映射和需求分页(英文名字:demand Paging,又叫:缺页中断)【转】

简介:

转自:http://blog.csdn.net/zhangxinrun/article/details/5873148

当某个程序映象开始运行时,可执行映象必须装入进程的虚拟地址空间。如果该程序用到了任何一个共享库,则共享库也必须装入进程的虚拟地址空间。实际上,Linux 并不将映象装入物理内存,相反,可执行文件只是被链接到进程的虚拟地址空间中(磁盘空间中)。随着程序的运行,被引用的程序部分会由操作系统装入物理内存。这种将映象链接到进程地址空间的方法称为“内存映射”。可执行映像.
每个进程的虚拟内存由一个 mm_struct 结构代表,我们将在下一章中详细讲述该结构。该结构中实际包含了当前执行映象的有关信息,并且包含了一组指向 vm_area_struct 结构的指针。如图 10-5 所示,每个 vm_area_struct 描述了一个虚拟内存区域的起点和终点、进程对内存的访问权限以及一个对内存的操作例程集。操作例程集是 Linux 操作该内存区域时所使用的例程集合。例如,当进程试图访问的虚拟内存当前不在物理内存当中时(通过页故障),Linux 就可以利用操作集中的一个例程执行正确的操作,在这种情况下为 nopage 操作。


        图 10-5 vm_area_struct 数据结构示意图
当可执行映象映射到进程的虚拟地址空间时,将产生一组 vm_area_struct 结构来描述虚拟内存区域的起始点和终止点,每个 vm_struct 结构代表可执行映象的一部分,可能是可执行代码,也可能是初始化的变量或未初始化的数据。随着 vm_area_struct 结构的生成,这些结构所描述的虚拟内存区域上的标准操作函数也由 Linux 初始化。
某个可执行映象映射到进程虚拟内存中并开始执行时,因为只有很少一部分装入了物理内存,因此很快就会访问尚未装入物理内存的虚拟内存区域。这时,处理器将向 Linux 报告一个页故障及其对应的故障原因。
这种页故障的出现原因有两种,一是程序出现错误,例如向随机物理内存中写入数据,这种情况下,虚拟内存是无效的,Linux 将向程序发送 SIGSEGV 信号并终止程序的运行;另一种情况是,虚拟地址有效,但其所对应的页当前不在物理内存中,这时,操作系统必须从磁盘映象或交换文件中将内存装入物理内存。
那么,Linux 如何判断页故障发生时,虚拟内存地址是否是有效的呢?如前所述,Linux 利用 vm_area_struct 数据结构描述进程的虚拟内存空间,为了查找出现页故障虚拟内存相应的 vm_area_struct 结构的位置,Linux 内核同时维护一个由 vm_area_struct 结构形成的 AVL(Adelson-Velskii and Landis)树。利用 AVL 树,可快速寻找发生页故障的虚拟地址所在的内存页区域。如果搜索不到这一内存区域,则说明该虚拟地址是无效的,否则该虚拟地址是有效的。
也有可能因为进程在虚拟地址上进行的操作非法而产生页故障,例如在只读页中写入数据。这时操作系统会同样发送内存错误信号到该进程。有关页的访问控制信息(只读页、只写页、可读可写页、可执行代码页等)包含在页表项中。
对有效的虚拟地址,Linux 必须区分页所在的位置,即判断页是在交换文件中,还是在可执行映象中。为此,Linux 通过页表项中的信息区分页所在的位置。如果该页的页表项是无效的,但非空,则说明该页处于交换文件中,操作系统要从交换文件装入页(有关内存交换的内容在下一节中讲述)。否则,默认情况下,Linux 会分配一个新的物理页并建立一个有效的页表项;对于映象的内存映射来讲,则会分配新的物理页,更新页表项属性信息,并从映象中装入页。
这时,所需的页装入了物理内存,页表项也同时被更新,然后进程就可以继续执行了。这种只在必要时才将虚拟页装入物理内存的处理称为“需求分页”。
在处理页故障的过程中,因为要涉及到磁盘访问等耗时操作,因此操作系统会选择另外一个进程进入执行状态。
















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5657811.html,如需转载请自行联系原作者

相关文章
|
3月前
|
存储 监控 算法
Java内存管理深度剖析:从垃圾收集到内存泄漏的全面指南####
本文深入探讨了Java虚拟机(JVM)中的内存管理机制,特别是垃圾收集(GC)的工作原理及其调优策略。不同于传统的摘要概述,本文将通过实际案例分析,揭示内存泄漏的根源与预防措施,为开发者提供实战中的优化建议,旨在帮助读者构建高效、稳定的Java应用。 ####
61 8
|
4月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
81 6
|
5月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
114 0
|
5月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
5月前
|
存储 缓存 监控
深入了解MySQL内存管理:如何查看MySQL使用的内存
深入了解MySQL内存管理:如何查看MySQL使用的内存
703 1
|
5月前
|
Java C语言 iOS开发
MacOS环境-手写操作系统-16-内存管理 解析内存状态
MacOS环境-手写操作系统-16-内存管理 解析内存状态
71 0
|
5月前
|
存储 安全 程序员
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
192 3
|
6月前
|
Java
在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?
【9月更文挑战第25天】在ArkTS中,有效进行内存管理并避免内存泄漏的方法包括:及时释放不再使用的资源,如关闭监听器和清理定时器;避免循环引用,通过弱引用打破循环;合理使用单例模式,确保单例对象正确释放;及时处理不再使用的页面和组件,在卸载时清理相关资源。
230 9
|
6月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
129 0
|
6月前
|
存储 并行计算 算法
CUDA统一内存:简化GPU编程的内存管理
在GPU编程中,内存管理是关键挑战之一。NVIDIA CUDA 6.0引入了统一内存,简化了CPU与GPU之间的数据传输。统一内存允许在单个地址空间内分配可被两者访问的内存,自动迁移数据,从而简化内存管理、提高性能并增强代码可扩展性。本文将详细介绍统一内存的工作原理、优势及其使用方法,帮助开发者更高效地开发CUDA应用程序。