计算机原理-操作系统-内核如何管理内存

1. 计算机底层原理 1 相关书籍推荐 读书原则:不求甚解,观其大略,大体读明白,先拿来用,用着用着,很多道理你就明白了 底层知识相关书籍 《编码:隐匿在计算机软硬件背后的语言》 《深入理解计算机系统》 C语言:《C程序设计语言》、《C Primer Plus》 数据结构:《Java数据结构与算法》、《算法》、《算法导论》、《计算机程序设计艺术》 操作系统:《Linux内核源码解析》、《Linux内核设计与实现》、《 30天自制操作系统》 网络:《TCP/IP详解-卷一》 编译原理:《编译原理》、《编程语言实现模式》 数据库 阅读详情

本文翻译自:http://duartes.org/gustavo/blog/

微信公众号:技术原理君

在之前的《进程的虚拟地址空间布局》文章之后,让我们把目光转向内核以及其管理用户内存的机制。我们从gonzo进程图示开始:

 

内核如何管理内存

 

Linux进程在内核中是由task_struct的实例来表示的,即进程描述符。task_struct的mm字段指向内存描述符(memory descriptor),即mm_struct,一个程序的内存的执行期摘要。它存储了上图所示的内存段的起止位置,进程所使用的物理内存页的数量(rss表示Resident Set Size),虚拟内存空间的使用量,以及其他信息。我们还可以在内存描述符中找到用于管理程序内存的两个重要结构:虚拟内存区域集合(the set of virtual memory areas)及页表(page table)。Gonzo的内存区域如下图所示:

内核如何管理内存

 

每一个虚拟内存区域(简称VMA)是一个连续的虚拟地址范围;这些区域不会交叠。一个vm_area_struct的实例完备的描述了一个内存区域,包括它的起止地址,决定访问权限和行为的标志位,还有vm_file字段,用于指出被映射的文件(如果有的话)。一个VMA如果没有映射到文件,则是匿名的(anonymous)。除memory mapping 段以外,上图中的每一个内存段(如:堆,栈)都对应于一个单独的VMA。这并不是强制要求,但在x86机器上经常如此。VMA并不关心它在哪一个段。

一个程序的VMA同时以两种形式存储在它的内存描述符中:一个是按起始虚拟地址排列的链表,保存在mmap字段;另一个是红黑树,根节点保存在mm_rb字段。红黑树使得内核可以快速的查找出给定虚拟地址所属的内存区域。当你读取文件/proc/pid_of_process/maps时,内核只须简单的遍历指定进程的VMA链表,并打印出每一项来即可。

在Windows中,EPROCESS块可以粗略的看成是task_struct和mm_struct的组合。VMA在Windows中的对应物时虚拟地址描述符(Virtual Address Descriptor),或简称VAD;它们保存在平衡树中(AVL tree)。你知道Windows和Linux最有趣的地方是什么吗?就是这些细小的不同点。

4GB虚拟地址空间被分割为许多页(page)。x86处理器在32位模式下所支持的页面大小为4KB,2MB和4MB。Linux和Windows都使用4KB大小的页面来映射用户部分的虚拟地址空间。第0-4095字节在第0页,第4096-8191字节在第1页,以此类推。VMA的大小必须是页面大小的整数倍。下图是以4KB分页的3GB用户空间:

内核如何管理内存

 

 

处理器会依照页表(page table)来将虚拟地址转换到物理内存地址。每个进程都有属于自己的一套页表;一旦进程发生了切换,用户空间的页表也会随之切换。Linux在内存描述符的pgd字段保存了一个指向进程页表的指针。每一个虚拟内存页在页表中都有一个与之对应的页表项(page table entry),简称PTE。它在普通的x86分页机制下,是一个简单的4字节记录,如下图所示:

 

内核如何管理内存

 

 

Linux有一些函数可以用于读取或设置PTE中的每一个标志。P位告诉处理器虚拟页面是否存在于(present)物理内存中。如果是0,访问这个页将触发页故障(page fault)。记住,当这个位是0时,内核可以根据喜好,随意的使用其余的字段。R/W标志表示读/写;如果是0,页面就是只读的。U/S标志表示用户/管理员;如果是0,则这个页面只能被内核访问。这些标志用于实现只读内存和保护内核空间。

D位和A位表示数据脏(dirty)和访问过(accessed)。脏表示页面被执行过写操作,访问过表示页面被读或被写过。这两个标志都是粘滞的:处理器只会将它们置位,之后必须由内核来清除。最后,PTE还保存了对应该页的起始物理内存地址,对齐于4KB边界。PTE中的其他字段我们改日再谈,比如物理地址扩展(Physical Address Extension)。

虚拟页面是内存保护的最小单元,因为页内的所有字节都共享U/S和R/W标志。然而,同样的物理内存可以被映射到不同的页面,甚至可以拥有不同的保护标志。值得注意的是,在PTE中没有对执行许可(execute permission)的设定。这就是为什么经典的x86分页可以执行位于stack上的代码,从而为黑客利用堆栈溢出提供了便利(使用return-to-libc和其他技术,甚至可以利用不可执行的堆栈)。PTE缺少不可执行(no-execute)标志引出了一个影响更广泛的事实:VMA中的各种许可标志可能会也可能不会被明确的转换为硬件保护。对此,内核可以尽力而为,但始终受到架构的限制。

虚拟内存并不存储任何东西,它只是将程序地址空间映射到底层的物理内存上,后者被处理器视为一整块来访问,称作物理地址空间(physical address space)。对物理内存的操作还与总线有点联系,好在我们可以暂且忽略这些并假设物理地址范围以字节为单位递增,从0到最大可用内存数。这个物理地址空间被内核分割为一个个页帧(page frame)。处理器并不知道也不关心这些帧,然而它们对内核至关重要,因为页帧是物理内存管理的最小单元。Linux和Windows在32位模式下,都使用4KB大小的页帧;以一个拥有2GB RAM的机器为例:

 

内核如何管理内存

 

 

在Linux中,每一个页帧都由一个描述符和一些标志所跟踪。这些描述符合在一起,记录了计算机内的全部物理内存;可以随时知道每一个页帧的准确状态。物理内存是用buddy memory allocation技术来管理的,因此如果一个页帧可被buddy 系统分配,则它就是可用的(free)。一个被分配了的页帧可能是匿名的(anonymous),保存着程序数据;也可能是页缓冲的(page cache),保存着一个文件或块设备的数据。还有其他一些古怪的页帧使用形式,但现在先不必考虑它们。Windows使用一个类似的页帧编号(Page Frame Number简称PFN)数据库来跟踪物理内存。

让我们把虚拟地址区域,页表项,页帧放到一起,看看它们到底是怎么工作的。下图是一个用户堆的例子:

内核如何管理内存

 

 

蓝色矩形表示VMA范围内的页,箭头表示页表项将页映射到页帧上。一些虚拟页并没有箭头;这意味着它们对应的PTE的存在位(Present flag)为0。形成这种情况的原因可能是这些页还没有被访问过,或者它们的内容被系统换出了(swap out)。无论那种情况,对这些页的访问都会导致页故障(page fault),即使它们处在VMA之内。VMA和页表的不一致看起来令人奇怪,但实际经常如此。

一个VMA就像是你的程序和内核之间的契约。你请求去做一些事情(如:内存分配,文件映射等),内核说"行",并创建或更新适当的VMA。但它并非立刻就去完成请求,而是一直等到出现了页故障才会真正去做。内核就是一个懒惰,骗人的败类;这是虚拟内存管理的基本原则。它对大多数情况都适用,有些比较熟悉,有些令人惊讶,但这个规则就是这样:VMA记录了双方商定做什么,而PTE反映出懒惰的内核实际做了什么。这两个数据结构共同管理程序的内存;都扮演着解决页故障,释放内存,换出内存(swapping memory out)等等角色。让我们看一个简单的内存分配的例子:

 

内核如何管理内存

 

 

当程序通过brk()系统调用请求更多的内存时,内核只是简单的更新堆的VMA,然后说搞好啦。其实此时并没有页帧被分配,新的页也并没有出现于物理内存中。一旦程序试图访问这些页,处理器就会报告页故障,并调用do_page_fault()。它会通过调用find_vma()去搜索哪一个VMA含盖了产生故障的虚拟地址。如果找到了,还会根据VMA上的访问许可来比对检查访问请求(读或写)。如果没有合适的VMA,也就是说内存访问请求没有与之对应的合同,进程就会被处以段错误(Segmentation Fault)的罚单。

当一个VMA被找到后,内核必须处理这个故障,方式是察看PTE的内容以及VMA的类型。在我们的例子中,PTE显示了该页并不存在。事实上,我们的PTE是完全空白的(全为0),在Linux中意味着虚拟页还没有被映射。既然这是一个匿名的VMA,我们面对的就是一个纯粹的RAM事务,必须由do_anonymous_page()处理,它会分配一个页帧并生成一个PTE,将出故障的虚拟页映射到那个刚刚分配的页帧上。

事情还可能有些不同。被换出的页所对应的PTE,例如,它的Present标志是0但并不是空白的。相反,它记录了页面内容在交换系统中的位置,这些内容必须从磁盘读取出来并通过do_swap_page()加载到一个页帧当中,这就是所谓的major fault。

至此我们走完了"内核的用户内存管理"之旅的前半程。在下一篇文章中,我们将把文件的概念也混进来,从而建立一个内存基础知识的完成画面,并了解其对系统性能的影响。

1. 操作系统导论 操作系统导论 计算机作用 抽象与分层。 1.操作系统的功能 2.计算机系统的组成 3.计算机系统的体系结构 4.操作系统的结构 5.操作系统的执行 6.进程管理 7.内存管理 8.存储管理 9.保护与安全 10.内核数据结构 11.计算环境 12.开源操作系统 13.小结 ... 阅读详情

相关推荐

Linux操作系统分析课程总结

Linux

weixin_40811476的博客 713

操作系统和内核有什么区别?

操作系统和内核的区别?看这篇就够了1 什么是内核2 什么是操作系统?3 操作系统和内核的区别? 1 什么是内核 内核是操作系统的核心。内核是操作系统执行的第一道程序,被率先加载到内存中开始系统行为。内核始终保持在主内存中直到系统被关闭。内核将用户输入的命令转换成计算机硬件能理解的机器语言。 内核是系统应用软件和硬件的桥梁。内核直接与硬件联系,并告之它由应用软件发起的请求。操作系统不能脱离内核工作,内核是系统正常运行最重要的程序。 内核的主要职责是:进程管理、磁盘管理、任务调度、内存管理。内核检测内存空间——

FRIGIDWINTER的博客 1万+

操作系统从零开始:ORANGE’S实现原理与实践

在编写内核初始化代码时,我们通常会使用C或C++语言,因为它们提供了足够的硬件控制能力,同时拥有良好的抽象级别。以下是一个简单的内核初始化代码示例:// 初始化硬件设备和中断控制器// 初始化内存管理单元// 设置内核的进程表和调度器// 启动系统关键服务// 进入主循环// 系统主循环,等待调度器安排进程执行在上述代码中,等函数都是内核初始化过程中必须实现的底层函数,它们负责设置和启动硬件设备、内存管理单元和中断控制器。函数用于创建内核的进程表,而。

weixin_30632267的博客 470

内核和内存的区别

转自:http://www.360kuai.com/pc/95216d24418f939e9?cota=4&kuai_so=1&sign=360_a9931de8&refer_scene=so_1 Linux系统一般有4个主要部分组成,内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统...

woainilixuhao的博客 7066

TWINCAT3保姆级教程:手把手教你给Ecat从站烧录EEPROM(含XML配置避坑指南)

本文提供TWINCAT3环境下Ecat从站EEPROM烧录的完整教程,涵盖XML配置避坑指南。详细讲解环境准备、设备扫描、XML文件配置、EEPROM烧录流程及故障排查,帮助工程师高效解决设备识别问题,提升产线调试效率。

weixin_30693683的博客 516

别再到处找了!GWAS数据下载保姆级指南:从IEU、FinnGen到UK Biobank一站搞定

本文提供GWAS数据下载的全面指南,涵盖IEU OpenGWAS、FinnGen、UK Biobank等五大核心数据库的获取策略。从数据库选型到实战操作,详细解析数据搜索、下载、预处理全流程,帮助科研人员高效获取GWAS数据,特别适合初学者快速上手。

weixin_42523543的博客 1584

操作系统的内存管理机制总结

参考链接:https://mp.weixin.qq.com/s/oexktPKDULqcZQeplrFunQ 虚拟内存 对于单片机而言,其 CPU 是直接操作内存的「物理地址」 在这种情况下,要想在内存中同时运行两个程序是不可能的。如果第一个程序在 2000 的位置写入一个新的值,将会擦掉第二个程序存放在相同位置上的所有内容,所以同时运行两个程序是根本行不通的,这两个程序会立刻崩溃 操作系统的解决方式 我们可以把进程所使用的地址「隔离」开来,即让操作系统为每个进程分配独立的一套「虚拟地址」,人人都有,

OriSu 4015

内网渗透(二)之基础知识-工作组介绍

在一个大型单位里,可能有成百上千台计算机互相连接组成局域网,它们都会列在"网络"(网上邻居)内。如果不对这些计算机进行分组,网络的混乱程度是可想而知的 为了解决这一问题,产生了工作组( Work Group)这个概念。将不同的计算机按功能(或部 门)分别列入不同的工作组,例如技术部的计算机都列入"技术部"工作组、行政部的计算机都 列入"行政部"工作组。要想访问某个部门的资源,只要在"网络"里双击该部门的工作组名 就可以看到该部门的所有计算机了。相比不分组的情况,这样的情况有序得多(尤其对大型局域网来说)。

把自己活成一道光,因为你不知道,谁会借着你的光,走出了黑暗。请保持心中的善良,因为你不知道,谁会借着你的善良,走出了绝望。请保持你心中的信仰,因为你不知道,谁会借着你的信仰,走出了迷茫。请相信自己的力量,因为你不知道,谁会因为相信你,开始相信了自己.... 1219

Linux内核内存管理

1、内存模型概览通常CPU可见的地址是有限制的,32位的CPU最多可见4GB的物理空间,64位的CPU可见的空间会更大。32位的系统一般都需要考虑通过“动态映射”方法拓展物理内存的可见性问题。通常程序访问的地址都是虚拟地址,用32位操作系统来讲,访问的地址空间为4G,linux将4G分为两部分。如图1所示,其中0~3G为用户空间,3~4G为内核空间。通过MMU这两部分空间都可以访问到实际的物理内存...

watermelonbig的专栏 2177

【Unity 实用工具篇】 | 滚动列表插件FancyScrollView,快速上手使用

FancyScrollView 是一款专为Unity引擎开发的高效滚动列表组件。它具有轻量级、可定制性强、性能优秀等特点。 使用FancyScrollView插件进行Unity项目开发,可以极大提升开发效率,尤其是在需要大量列表展示的场景下,如商城、目录列表、角色选择界面等。开发者可以将注意力集中在业务逻辑的实现上,而将界面渲染和交互部分交由FancyScrollView处理。 本文来介绍一下FancyScrollView的功能展示和基本使用方法。

努力前行,总会成为自己心中的那道光 3万+

自适应滤波器在噪声消除中的应用:系统设计与实现

本文设计并实现了一种基于LMS算法的自适应噪声消除系统,能够有效消除周期性背景噪声,提升信噪比10dB以上。系统采用模块化设计,包含音频输入、自适应滤波、信号分析和可视化等核心模块,支持实时处理与参数动态调整。通过Python实现,提供图形界面进行参数设置、频谱对比和音频播放功能,为语音增强提供了一种实用解决方案。

huanghm88的专栏 128

操作系统是如何管理内存的

前言 每个进程创建的内存地址都是虚拟地址,操作系统使用了虚拟化技术,让进程觉得它拥有了大块可支配的内存的假象,操作系统拿到这个地址后会将它转变为真实的内存地址,从而拿到对应的信息。比如下面这段代码: #include  #include  int main(int argc, char *argv[]) { printf("location of code : %p\n", (void *)...

asdf8968的博客 1万+

历年安徽省省赛AHOI初中组考点分类汇总考点分类汇总

持续更新中.....

weixin_42358969的博客 818

操作系统内核与设计原理笔记

文章目录操作系统内核与设计原理笔记第1章 计算机系统概述1.1 基本构成1.2 微处理器的发展演化1.3 指令的执行1.4 中断1.5 存储器的层次结构1.6 高速缓存1.7 直接内存存取(DMA)1.8 多处理器和多喝计算机组织结构第2章 操作系统概述2.1 操作系统的目标和功能2.2 操作系统的发展2.3 主要成就2.4 现代操作系统的特征第3章 进程描述和控制3.1 什么是进程3.2 进程状态3.3 进程描述3.4 进程控制3.5 操作系统的执行第4章 线程4.1 进程和线程4.2 用户级和内核级线程

tthere的博客 1446

Qt图形几何之QRect详解:从基础操作到高级功能全解析

本文全面介绍了Qt框架中的QRect类,详细解析了其核心功能和使用方法。主要内容包括:1)QRect的基本概念与多种构造函数;2)矩形属性获取和状态判断方法;3)几何操作函数(移动、调整大小等);4)几何关系判断(包含、相交等);5)坐标变换和边距处理;6)实用功能与QRectF转换;7)综合应用示例(图形界面、碰撞检测、布局管理);8)性能优化建议和常见陷阱。通过丰富的代码示例,展示了QRect在Qt图形编程中的实际应用,帮助开发者掌握矩形处理的各项操作技巧,提升图形界面开发效率。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 117

[Dify] 实现“多知识库切换”功能的最佳实践

知识库切换是提升AI问答系统精准度的关键技术。本文介绍了Dify平台实现多知识库切换的三种方式:静态配置、元数据过滤和动态切换,分析了各自的优缺点。最佳实践建议包括:合理分库设计、意图分类、主库优先检索等。文章还提供了示例工作流程和注意事项,帮助构建更智能、精准的知识驱动型问答系统。通过合理切换知识库,可显著提升回答相关性和系统性能。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 441

《操作系统精髓与设计原理》学习笔记

文章目录置顶第一章:计算机系统概述1. 基本构成2. 指令分类3. 中断中断的分类多个中断4. 内存层次板上存储器板外存储器离线存储器5. 高速缓存6. 多处理器和多核多处理器多核二者区别第二章:操作系统概述1. Linux主要内核组件2. Windows和Android先不整理,以后需要再学第三章:进程1. 进程介绍进程的两个基本元素进程控制块(PCB)2. 进程状态经典5状态挂起态3. 操作系...

LvPartner的博客 3709

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

DOS操作系统内核剖析(下册)

DOS操作系统内核剖析(下册) 去发现同类优质开源项目:https://gitcode.com/ 本仓库提供了一本经典计算机操作系统书籍《DOS操作系统内核剖析(下册)》的下载资源,深入剖析了DOS操作系统的内核结构和原理。 简介 《DOS操作系统内核剖析(下册)》详细介绍了DOS操作系统的内部工作原理,包括文件管理、内存管理、进程管理等方面。本书适合对操作系统原理感兴趣的读者,以及希望深入了解D...

gitblog_06789的博客 386

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

操作系统——概述

文章目录什么是操作系统操作系统结构Linux 内核 vs Windows 内核内核什么是内核呢?内核有哪些能力呢?内核是怎么工作的?计算机启动过程系统调用UNIX 系统调用Windows系统调用 什么是操作系统 不知道你有没有产生过这些疑问: 桌面上的图标到底是啥?凭啥我在鼠标上一双击,就会出来一个美丽的画面?这都是从哪里跑出来的? 凭什么我在键盘上噼里啪啦地敲,某个位置就会显示我想要的那些字符? 电脑怎么知道我鼠标点击的是这个地方,又是怎么知道我要输入的是这个地方? 我在键盘上点“a”,是谁在显示器上画

zhouhengzhe的博客 7488

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【linux系统编程】初步理解操作系统设计原理

简单理解操作系统 1. 操作系统定位: 1.1 操作系统概览: 操作系统(英文:Operating System,缩写:OS)是一组主管并控制计算机操作、运用和运行硬件、软件资源和提供公共服务来组织用户交互的相互关联的系统软件程序,同时也是计算机系统的内核与基石。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面。 操作系统的类型非常多样,不同机器安装的操作系统可从简单到复杂,可从移动电话的嵌入式系

NingHai's blog 2883

2013年暑期补课计算机操作系统原理

2013年暑期补课计算机操作系统原理 什么是操作系统?计算机是如何工作的?操作系统又是如何在计算机上运行的?从这些基本的问题出发,我们一起探索操作系统的奥秘,并动手编写一个自己的操作系统内核,在这个过程中我们需要学习使用C语言、简单的汇编和嵌入式汇编、Linux操作系统的基本接口等。当然还要庖丁解牛式地一一考察学习进程、进程调度、内存管理、文件系统、I/O设备等操作系统的主要构成和相关理论。

linuxarmsummary的专栏 876

计算机科学与技术专业的高级操作系统的答案汇总

它将操作系统的核心功能(如进程管理、内存管理)作为最小的、精简的内核服务,而将其他高级功能(如文件系统、网络协议栈)放在用户空间的服务进程中实现。进程地址空间的布局( VMA 起始地址 结束地址 rwxp权限, map file, 代码段,数据段,栈,匿名段, 程序各部分位于进程地址空间的哪个段?在提供的信息中,slabdata行的列表示每个slab含有的对象数量,将所有值相加即可得到此slab含有的对象数量。对于其他的slab,可以按照类似的方式进行计算。

CZW1234R的博客 569

x86架构操作系统内核的实现

@toc 1.x86架构操作系统内核的实现 x86架构操作系统内核的实现

嵌入式与人工智能 803

1.操作系统概述

操作系统介绍1.1什么是操作系统1.2为什么学习系统1.3如何学习操作系统1.4操作系统实例1.5操作系统的历史1.6操作系统结构1.7小结 1.1什么是操作系统 1.2为什么学习系统 1.3如何学习操作系统 1.4操作系统实例 1.5操作系统的历史 1.6操作系统结构 1.7小结 ...

weixin_51864831的博客 311

操作系统到底是干什么的?使用场景是什么?底层原理是什么?

操作系统(Operating System,简称 OS)是计算机系统中最核心的软件之一,它负责管理和协调计算机硬件与软件资源。

长风破浪会有时的博客 2326

什么是操作系统?

操作系统简要概述

weixin_42065178的博客 338
上一篇: 计算机原理-操作系统-剖析程序的内存布局
下一篇: 计算机原理-操作系统- 转发 微博 Qzone 微信 Linux内核中的数据结构和算法
shankusu2017
博客等级 码龄15年 155粉丝 155原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值