缺页中断

Linux内存分配机制

不羁岁月 提交于 2020-03-07 14:07:34
原文:https://blog.csdn.net/gfgdsg/article/details/42709943 Linux 的虚拟内存管理有几个关键概念: 1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; 2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址; 3、如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。 基于以上认识,进行了如下分析: 一、Linux 虚拟地址空间如何分布? Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为: 1、只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) ) 2、数据段:保存全局变量、静态变量的空间; 3、堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。 4、文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。 5、栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。 6、内核虚拟空间

模拟操作系统的存储系统实验(Java语言描述)

天大地大妈咪最大 提交于 2020-01-26 18:07:53
模拟分页式存储管理中硬件的地址转换和产生缺页中断 (1)分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存,页表的格式为: 标志——用来表示对应页是否已经装入主存,标志位=1,则表示该页已经在主存,标志位=0,则表示该页尚未装入主存。 主存块号——用来表示已经装入主存的页所占的块号。 在磁盘上的位置——用来指出作业副本的每一页被存放在磁盘上的位置。 (2)作业执行时,指令中的逻辑地址指出了参加运算的操作数存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式: 绝对地址=块号×块长+单元号 计算出欲访问的主存单元地址。如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。按计算出的绝对地址可以取到操作数,完成一条指令的执行。若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,由操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。 (3)设计一个“地址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。当访问的页不在主存时,则输出“

操作系统核心原理-5.内存管理(中):分页内存管理

北城余情 提交于 2020-01-23 21:24:23
   在上一篇介绍的几种多道编程的内存管理模式中,以交换内存管理最为灵活和先进。但是这种策略也存在很多重大问题,而其中最重要的两个问题就是空间浪费和程序大小受限。那么有什么办法可以解决交换内存存在的这些问题呢?答案是分页,它是我们解决交换缺陷的“不二法门”。 一、分页内存管理 1.1 解决问题之道   为了解决交换系统存在的缺陷,分页系统横空出世。分页系统的核心在于: 将虚拟内存空间和物理内存空间皆划分为大小相同的页面,如4KB、8KB或16KB等,并以页面作为内存空间的最小分配单位,一个程序的一个页面可以存放在任意一个物理页面里 。   (1)解决空间浪费碎片化问题   由于将虚拟内存空间和物理内存空间按照某种规定的大小进行分配,这里我们称之为页(Page),然后按照页进行内存分配,也就克服了外部碎片的问题。   (2)解决程序大小受限问题   程序增长有限是因为一个程序需要全部加载到内存才能运行,因此解决的办法就是使得一个程序无须全部加载就可以运行。使用分页也可以解决这个问题,只需将当前需要的页面放在内存里,其他暂时不用的页面放在磁盘上,这样一个程序同时占用内存和磁盘,其增长空间就大大增加了。而且,分页之后,如果一个程序需要更多的空间,给其分配一个新页即可(而无需将程序倒出倒进从而提高空间增长效率)。 1.2 虚拟地址的构成与地址翻译   (1)虚拟地址的构成   在分页系统下

频繁分配释放内存导致的性能问题的分析

和自甴很熟 提交于 2020-01-18 06:37:13
频繁分配释放内存导致的性能问题的分析 现象 1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看,发现majflt每秒增量为0,而minflt每秒增量大于10000。 初步分析 majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误。 这两个数值表示一个进程自启动以来所发生的缺页中断的次数。 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 检查要访问的虚拟地址是否合法 查找/分配一个物理页 填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 建立映射关系(虚拟地址到物理地址) 重新执行发生缺页中断的那条指令 如果第3步,需要读取磁盘,那么这次缺页中断就是majflt,否则就是minflt。 此进程minflt如此之高,一秒10000多次,不得不怀疑它跟进程内核态cpu消耗大有很大关系。 分析代码 查看代码,发现是这么写的:一个请求来,用malloc分配2M内存,请求结束后free这块内存。看日志,发现分配内存语句耗时10us,平均一条请求处理耗时1000us 。 原因已找到! 虽然分配内存语句的耗时在一条处理请求中耗时比重不大,但是这条语句严重影响了性能

缺页中断

隐身守侯 提交于 2020-01-07 04:54:24
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 什么是缺页中断: 在计算机系统中,为了提高主存利用率,往往把辅助存储器(如磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间总和可以超出主存的绝对地址空间。用这种办法扩充的主存储器称为虚拟存储器。 模拟分页式存储管理中硬件的地址转换和产生缺页中断。分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业 被选中时,可把作业的开始几页先装入主存且启动执行。为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存。 作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式“绝对地址=块号×块长+单元号”计算出欲访问的主存单元地址。如果块长为2 的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而成绝对地址。若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,有操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。设计一个“地址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时,则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。当访问的页不在主存时,则输出“* 该页页号”,表示产生了一次缺页中断。

操作系统原理之存储问题

泪湿孤枕 提交于 2020-01-01 07:51:48
1. 某个OS采用可变分区分配方法管理,用户主存512KB,自由区由可用空区表管 理。若分配时采用分配自由区的低地址部分的方案,假设初始时全为空。对于 下列申请顺序: 申请(300KB), 申请(100KB), 释放(300KB), 申请(150KB),申请 (30KB),申请(40KB),申请(60KB),释放(30KB)。 回答下列问题: ( 1) 采用首次适应( FF),自由空区中有哪些空块(给出地址和大小)? ( 2) 若采用最佳适应( BF),回答( 1)中的问题。 ( 3) 如果再申请100KB,针对( 1)和( 2)各有什么结果? 1 )如图    空闲区: 起始地址: 150K 280K 400K 大小: 30K 20K 112K (2) 如图                         空闲区: 起始地址: 210K 400K 470K 大小: 90K 30K 42K (3) 针对( 1 ) 可分配在 400K 位置 针对( 2 ) 无法分配 2. 考虑下面的页访问串: 1,2,3,4,2,1,5,6,2,1,2,3,7,6,3,2,1,2,3,6 假定有4,5,6个页块, 应用下面的页面替换算法,计算各会出现多少次缺页中断。注意,所给定的页 块初始均为空,因此,首次访问一页时就会发生缺页中断。 ( 1) LRU ( 2) FIFO ( 3) Optimal

一次由缺页中断引发的旅程

匆匆过客 提交于 2019-12-01 18:38:28
综述 首先,啥是页,这是针对内存来说的,现代操作系统将内存分成许许多多的 页 (逻辑上),一页的大小默认是4KB(Linux)。操作系统在运行程序时,不会一次性将程序所需的页都加载到内存中(没有这个必要)。 所以当操作系统运行程序所要用到页没有加载到 物理内存 时,就会触发一个来自CPU的 缺页 错误,操作系统捕捉到这个错误,然后将对应的页加载到物理内存中。 上面的概述涉及到几个概念:页、物理内存、中断。 页和段 除了将内存划分成页之外,其实还可以划分成段,一段内存就存放程序所需要的全部数据和指令。这种情况下是不会产生缺少数据或者指令的情况的。不过却会引发一个新的问题:内存碎片和内存不足。如下图所示: 当然也有办法解决,就是 内存交换 ,将python程序占用的256M先写到硬盘上,再从硬盘上读回内存,不过是从接着已占用的512M写。这样我们就可以空间连续的256M来加载新的程序X了。看来很完美,不需要页的 出场了,实际上大家都知道,硬盘的访问速度相比内存来说,慢了可是几个数量级。频繁的读写磁盘,性能肯定上不去的,所以才有页的出现。 异常和中断 程序不仅简单的执行指令,更多的还需要和外部的输入输出打交道。另一方面,程序在运行过程中,还会遇到各种上异常情况,比如除0,位溢出,甚至我们自己也可以让程序招聘异常 异常,其实是一个硬件和软件组合在一起的处理过程,异常的前半生:发生和捕捉