(转载)深入理解Linux中内存管理---分段与分页简介

首先,必须要阐述一下这篇文章的主题是Linux内存管理中的分段和分页技术。

来回顾一下历史,在早期的计算机中,程序是直接运行在物理内存上的。换句话说,就是程序在运行的过程中访问的都是物理地址。如果这个系统只运行一个程序,那么只要这个程序所需的内存不要超过该机器的物理内存就不会出现问题,也就不需要考虑内存管理这个麻烦事了,反正就你一个程序,就这么点内存,吃不吃得饱那是你的事情了。然而现在的系统都是支持多任务,多进程的,这样CPU以及其他硬件的利用率会更高,这个时候就要考虑到将系统内有限的物理内存如何及时有效的分配给多个程序了,这个事情本身就称之为内存管理。

下面举一个早期的计算机系统中,内存分配管理的例子,以便于大家理解。

加入三个程序,程序1,2,3.程序1运行的过程中需要10M内存,程序2运行的过程中需要100M内存,而程序3运行的过程中需要20M内存。如果系统同时需要运行程序A和B,那么早期的内存管理过程大概是这样的,将物理内存的前10M分配给A, 接下来的10M-110M分配给B。这种内存管理的方法比较直接,好了,假设这个时候想让程序C也运行,同时假设系统的内存只有128M,显然按照这种方法程序C由于内存不够是不能够运行的。大家知道可以使用虚拟内存的技术,内存空间不够的时候可以将程序不需要用到的数据交换到磁盘空间上去,已达到扩展内存空间的目的。下面来看看这种内存管理方式存在的几个比较明显的问题。就像文章一开始提到的,要很深层次的把握某个技术最好搞清楚其发展历程。

1.进程地址空间不能隔离

由于程序直接访问的是物理内存,这个时候程序所使用的内存空间不是隔离的。举个例子,就像上面说的A的地址空间是0-10M这个范围内,但是如果A中有一段代码是操作10M-128M这段地址空间内的数据,那么程序B和程序C就很可能会崩溃(每个程序都可以系统的整个地址空间)。这样很多恶意程序或者是木马程序可以轻而易举的破快其他的程序,系统的安全性也就得不到保障了,这对用户来说也是不能容忍的。

2. 内存使用的效率低

如上面提到的,如果要像让程序A、B、C同时运行,那么唯一的方法就是使用虚拟内存技术将一些程序暂时不用的数据写到磁盘上,在需要的时候再从磁盘读回内存。这里程序C要运行,将A交换到磁盘上去显然是不行的,因为程序是需要连续的地址空间的,程序C需要20M的内存,而A只有10M的空间,所以需要将程序B交换到磁盘上去,而B足足有100M,可以看到为了运行程序C需要将100M的数据从内存写到磁盘,然后在程序B需要运行的时候再从磁盘读到内存,知道IO操作比较耗时,所以这个过程效率将会十分低下。

3. 程序运行的地址不能确定

程序每次需要运行时,都需要在内存中非配一块足够大的空闲区域,而问题是这个空闲的位置是不能确定的,这会带来一些重定位的问题,重定位的问题确定就是程序中引用的变量和函数的地址,如果有不明白童鞋可以去查查编译愿意方面的资料。

内存管理无非就是想办法解决上面三个问题,如何使进程的地址空间隔离,如何提高内存的使用效率,如何解决程序运行时的重定位问题?

这里引用计算机界一句无从考证的名言:“计算机系统里的任何问题都可以靠引入一个中间层来解决。”

现在的内存管理方法就是在程序和物理内存之间引入了虚拟内存这个概念。虚拟内存位于程序和屋里内存之间,程序只能看见虚拟内存,再也不能直接访问物理内存。每个程序都有自己独立的进程地址空间,这样就做到了进程隔离。这里的进程地址空间是指虚拟地址。顾名思义既然是虚拟地址,也就是虚的,不是现实存在的地址空间。

既然在程序和物理地址空间之间增加了虚拟地址,那么就要解决怎么从虚拟地址映射到物理地址,因为程序最终肯定是运行在物理内存中的,主要有分段和分页两种技术。

分段(Segmentation):这种方法是人们最开始使用的一种方法,基本思路是将程序所需要的内存地址空间大小的虚拟空间映射到某个
物理地址空间。

段映射机制

每个程序都有其独立的虚拟的独立的进程地址空间,可以看到程序A和B的虚拟地址空间都是从0x00000000开始的。将两块大小相同的虚拟地址空间和实际物理地址空间一一映射,即虚拟地址空间中的每个字节对应于实际地址空间中的每个字节,这个映射过程由软件来设置映射的机制,实际的转换由硬件来完成。

这种分段的机制解决了文章一开始提到的3个问题中的进程地址空间隔离和程序地址重定位的问题。程序A和程序B有自己独立的虚拟地址空间,而且该虚拟地址空间被映射到了互相不重叠的物理地址空间,如果程序A访问虚拟地址空间的地址不在0x00000000-0x00A00000这个范围内,那么内核就会拒绝这个请求,所以它解决了隔离地址空间的问题。应用程序A只需要关心其虚拟地址空间0x00000000-0x00A00000,而其被映射到哪个物理地址无需关心,所以程序永远按照这个虚拟地址空间来放置变量,代码,不需要重新定位。

无论如何分段机制解决了上面两个问题,是一个很大的进步,但是对于内存效率问题仍然无能为力。因为这种内存映射机制仍然是以程序为单位,当内存不足时仍然需要将整个程序交换到磁盘,这样内存使用的效率仍然很低。那么,怎么才算高效率的内存使用呢。事实上,根据程序的局部性运行原理,一个程序在运行的过程当中,在某个时间段内,只有一小部分数据会被经常用到。所以需要更加小粒度的内存分割和映射方法,此时是否会想到Linux中的Buddy算法和slab内存分配机制呢,哈哈。另一种将虚拟地址转换为物理地址的方法分页机制应运而生了。

分页机制

分页机制就是把内存地址空间分为若干个很小的固定大小的页,每一页的大小由内存决定,就像Linux中ext文件系统将磁盘分成若干个Block一样,这样做是分别是为了提高内存和磁盘的利用率。试想以下,如果将磁盘空间分成N等份,每一份的大小(一个Block)是1M,如果我想存储在磁盘上的文件是1K字节,那么其余的999字节是不是浪费了。所以需要更加细粒度的磁盘分割方式,可以将Block设置得小一点,这当然是根据所存放文件的大小来综合考虑的,好像有点跑题了,我只是想说,内存中的分页机制跟ext文件系统中的磁盘分割机制非常相似。

Linux中一般页的大小是4KB,把进程的地址空间按页分割,把常用的数据和代码页装载到内存中,不常用的代码和数据保存在磁盘中,还是以一个例子来说明,如下图:


进程虚拟地址空间、物理地址空间和磁盘之间的页映射关系

可以看到进程1和进程2的虚拟地址空间都被映射到了不连续的物理地址空间内(这个意义很大,如果有一天连续物理地址空间不够,但是不连续的地址空间很多,如果没有这种技术,程序就没有办法运行),甚至他们共用了一部分物理地址空间,这就是共享内存。

进程1的虚拟页VP2和VP3被交换到了磁盘中,在程序需要这两页的时候,Linux内核会产生一个缺页异常,然后异常管理程序会将其读到内存中。

这就是分页机制的原理,当然Linux中的分页机制的实现还是比较复杂的,通过了也全局目录,也上级目录,页中级目录,页表等几级的分页机制来实现的,但是基本的工作原理是不会变的。

分页机制的实现需要硬件的实现,这个硬件名字叫做MMU(Memory Management Unit),他就是专门负责从虚拟地址到物理地址转换的,也就是从虚拟页找到物理页。

转载于:https://www.cnblogs.com/hello2mhb/articles/3359047.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse解决Android Library Project jar包重复导致的问题

Android Studio部分情况下用起来还是有些不适应的地方,用eclipse熟练了,在赶项目进度的情况下还得重拾eclipse。下面是今天碰到的一个老问题。 1.在导入Android Library工程文件的时候要把library一起拷贝到workspace中 2.在导入的Android Library工程文…

java中main函数的args参数

先说一下args的作用:我们习惯将一些有用的参数传递给我们定义的函数,那么可曾想过有参数传递给main函数?args就是传递给main函数的一个数组参数。可是main函数作为程序(application程序)的入口点,是由系统自动调用的,怎…

算法:排序算法的比较

默认为递增顺序&#xff1b;注&#xff1a;一下例子希望自己再次复习时&#xff0c;可以用笔在纸上画画内存图。 包括有: 选择排序冒泡排序插入排序 1.选择排序 <--------------------------------------选择排序---------------------------------------> 1、选择排…

LTTng 简介使用实战

一、LTTng简介 LTTng: (Linux Trace Toolkit Next Generation),它是用于跟踪 Linux 内核、应用程序以及库的系统软件包。LTTng 主要由内核模块和动态链接库(用于应用程序和动态链接库的跟踪)组成。它由一个会话守护进程控制,该守护进程接受来自命令行接口的命令。babeltrace 项…

黑马程序员-------------(十)Java基础知识加强(一)

JDK1.5新特性 目录1.之前已经学习过的JDK1.5新特性2.静态导入 StaticImport3.可变参数 ...4.高级for循环5.枚举6.泛型 Generic7.注解注&#xff1a;本章全部为重点内容。###################################################################################################…

java例子:数组 数3退1

500个人围成一个圈子&#xff0c;数够3人&#xff0c;就退出1个&#xff0c;问最后剩下的是几号&#xff1f;检验先有5个人&#xff0c;应该留下第4个人&#xff0c;由于是数组&#xff0c;所以第四个人的下标是3. /*achieve the funtion :count 3 kids, the quit the third k…

Android版CCLabelTTF在setstring时出现黑块

首先有个前提知识&#xff0c;cocos2dx里&#xff0c;只能在ui线程&#xff08;通常也就是主线程&#xff09;中进行渲染工作&#xff08;貌似现在有一些引擎是支持多线程渲染的&#xff0c;没有深入研究&#xff09;&#xff0c;否则大约会因为多个线程同时给GPU发指令而出现问…

java例子:九九乘法表

来吧直接上代码&#xff1a;public class Test{public static void main(String[] args) {for(int i 1; i<9;i){for (int j 1; j < i ;j ) {System.out.print(j"x"i""j*i" ");}System.out.print("\n");}} }运行之后&#xff1…

Apache的RewriteRule规则详细介绍

R[code](force redirect) 强制外部重定向 (rkyW z强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定&#xff0c;将用缺省的302 HTTP状态码。 gN24M 3{CF(force URL to be forbidden)禁用URL,返回403HTTP状态码。 m> 4ahue$G(force URL…

算法:查找

查找算法&#xff08;比较&#xff09;基本思想顺序查找顺序查找也称为线形查找&#xff0c;属于无序查找算法。从数据结构线形表的一端开始&#xff0c;顺序扫描&#xff0c;依次将扫描到的结点关键字与给定值k相比较&#xff0c;若相等则表示查找成功&#xff1b;若扫描结束仍…

query上传插件uploadify参数详细分析

query上传插件uploadify参数详细分析 Uploadify Version 3.2 官网&#xff1a;http://www.uploadify.com/ 注&#xff1a;文件包里有两个js分别是&#xff1a;jquery.uploadify.js 和 jquery.uploadify.min.js&#xff0c;两者其实一样&#xff0c;只需载入其中一个js即可。很明…

python 基础 list和 tuple dict和set

list Python内置的一种数据类型是列表&#xff1a;list。list是一种有序的集合&#xff0c;可以随时添加和删除其中的元素。classmates [Michael, Bob, Tracy] 要删除list末尾的元素&#xff0c;用pop()方法&#xff1a; 要删除指定位置的元素&#xff0c;用pop(i)方法&#x…

IIS的安装

xp上好像只能装IIS5&#xff0c;IIS6根本就装不了转载于:https://www.cnblogs.com/hyk110988/p/3372592.html

py四种时间格式

time有四种类型&#xff08;time, datetime, string, timestamp&#xff09;1. time stringstring是最简单的表示time的方式如如下代码生成的即为string123>>> import time>>> time.ctime()Wed Nov 30 13:53:31 2016或者更简单的生成一个字符串1time_string …

type_traits应用

工作遇到这样的例子&#xff0c;对不同数据进行计算处理&#xff0c;得到一组结果集&#xff0c;包括计数、比例等。各个计算处理过程不同&#xff0c;结果集数据结构相同&#xff0c;但并非所有计算过程均有计数、比例的结果&#xff0c;有些可能只有计数&#xff0c;有些只有…

csv.writer写入文件有多余的空行

在用csv.writer写入文件的时候发现中间有多余的空行。 最早打开方式只是‘w’&#xff0c;会出现多余的空行&#xff0c;网上建议使用binary形式‘wb’打开可以解决问题&#xff1a; with open(egg2.csv, wb) as cf:12 不过只能在python2下运行&#xff0c;python3报错&#xf…

java笔记之连接数据库

1、一定不要忘了导入包 java工程&#xff1a;lib文件夹下mysql-connector-java.jar--->Build Path Web工程:当web下的servlet需要连接数据库时&#xff0c;除了上一步导入包还要在WEB-INF/lib导入mysql-connector-java.jar 2、关于乱码&#xff0c;查询 在终端查询数据时&am…

那些不能错过的XCode插件

XCode颜色显示插件ColorSense代码里的那些冷冰冰的颜色数值&#xff0c;到底时什么颜色&#xff1f;如果你经常遇到这个问题&#xff0c;每每不得不运行下模拟器去看看&#xff0c;那么这个插件绝对不容错过。更彪悍的是你甚至可以点击显示的颜色面板&#xff0c;直接通过系统的…

python爬虫第一课 开发环境配置

一、Python3的安装 二、请求库的安装 1、requests的安装 直接pip安装&#xff1a;pip3 install requests 2、Selenium的安装 selenium是一个自动测试化工具&#xff0c;利用它我们可以驱动浏览器执行特定的动作&#xff0c;如点击、下拉等操作。 直接pip安装&#xff1a;pip in…

用JSLint精炼提升JavaScript代码

由于移动应用的盛行和HTML5的广泛运用&#xff0c;JavaScript正越来越流行。JavaScript受欢迎的部分原因是因为它的灵活便捷&#xff0c;你可以快速上手&#xff0c;它不需要重量级的开发环境&#xff0c;也不需要第三方应用支持&#xff0c;只要你打开一个文本编辑器&#xff…