段,页,段页,三种内存(RAM)管理机制分析

2024-06-24 09:36

本文主要是介绍段,页,段页,三种内存(RAM)管理机制分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

段,页,段页

        是为实现虚拟内存而产生的技术。直接使用物理内存弊端:地址空间不隔离,内存使用效率低。

段:就是按照二进制文件的格式,在内存给进程分段(包括堆栈、数据段、代码段)。通过段寄存器中的段表来进行虚拟地址和物理地址的转换。

段实现的虚拟地址 = 段号+offset

物理地址:被分为很多个有编号的段,每个进程的虚拟地址都有段号,这样可以实现虚实地址之间的转换。其实所谓的地址映射,就是虚实地址转换之间的那个公式。

经过上面的理解我们知道了,实现段机制的器件其实就是段寄存器(段表)

不足:内存碎片(程序结束后内存被分割为一小块一小块),解决方法是SWAP分区(将散开的进程读出来再粘贴到另一个进程边上,使空闲的内存是连贯的,但这样效率很低)

页:就是将物理内存固定大小地分为n个页(linux中是4KB一页)。通过MMU的页表来进行虚实地址转换,这里就不是用寄存器来实现了。页表记录着页号、页号对应的物理地址,比较创新的是还记录着权限。基本功能已经有了,就是物理地址和页号怎么对应上。

页实现的虚拟地址 = 页号 + 页内偏移

物理地址:被分为很多个有编号的页,每个进程的虚拟地址都是用页号和偏移来记录,通过MMU来进行虚实转换。

经过上面的理解我们知道了,实现页机制的器件其实就是MMU。

优点:为什么说MMU可以让原本1G SDRAM的物理内存,实现能够实际使用4G SDRAM空间?甚至给每个程序都安排上4G SDRAM的内容空间?为什么每一个进程的内存空间是独立的?

就是因为物理SDRAM用页来管理,有些不用的页,可以暂时先存到硬盘上,硬盘的空间就非常大了动不动就是几百个G,所以可以做到虚拟出很大的内存空间给到程序。因为每一个进程都有自己单独的页表,一个进程根本没法知道或者操作另一个进程的页表,对应的也就不知道另一个进程的地址(虚拟地址对应的物理地址)在哪里,自然就是独立的。

缺点:页表本身占用的内存太多了,每一个进程有一个页表,那么理论上32位的机器4G的物理内存,每一页是4K的话,总共会有4G/4K = 2^10 * 2*10 个页表,如果一个页表要4MB,那光是记录页表就要占用800M的内存。

解决:套娃,用多级页表。

采用多级页表机制的虚拟地址 = 一级页号 + 二级页号 + 页内偏移。这样MMU可以通过页号1来找到页号2,通过页号2+页内偏移来找到对应的物理地址从而实现虚实转换。那为啥这样能够降低页表占用内存的大小呢?其实就行把文件折叠了一样,如果一级页表里面有的二级页表没有被分配,那这些二级页表实际上就是没有分配内存的;如果有些二级页表很久没有被使用,那这些二级页表也可以暂时存到硬盘里,也不占用空间。假如一个一级页表是4MB的话,那就相当于你可以用1个4MB的内存大小去管理很多个占4MB的二级页表,然而实际只占用了4MB。照着这个思路,可以造出很多级的页表,进行极致的页表空间压缩。

缺点2:多级页表是省了空间,但是从虚拟地址转成物理地址也多了很多步骤,要一级一级地查找最终才能找到对应的物理地址。

解决2:建立快表TLB,实际就是把一些最近使用的进程它虚拟地址对应的最底层页号和偏移,存到一个一级表中(快表),这样要地址转换时,先去快表找,找不到再去查多级页表。如此就显著提高了虚实地址转换速度,而且也节省了空间。

段页式

段页式:其实就是把物理地址分为一大段一大段的,在段的内部,再进行分页。

段页式机制下虚拟地址 = 段号 + (段内)页号 + 页内偏移

这样就结合了段(契合二进制文件堆栈,代码段,数据段分层,便于程序分配地址)和页(多级页表节省空间)两个特点。

不足:就是实现起来比较复杂。但是段页式是现在内存(SDRAM)管理的主流。需要注意的是,Linux是使用页机制的。

但是linux中的页机制也一定程度上有段页结合的影子,下面是段页式的虚实地址转换流程:

linux中每一个进程虚拟地址中的段号都是对应的0~4GB的地址空间,每一个进程段空间范围都一样就意味着虚拟地址中的段号没有划分地址的作用,实际上linux中的虚拟地址是 "虚拟地址 = 段号+页号+页内偏移 ",系统有规定某些段号只有内核程序能使用,应用层程序只能使用另一些段号。从而实现了访问权限的机制。

这篇关于段,页,段页,三种内存(RAM)管理机制分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089772

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文

React 记忆缓存的三种方法实现

《React记忆缓存的三种方法实现》本文主要介绍了React记忆缓存的三种方法实现,包含React.memo、useMemo、useCallback,用于避免不必要的组件重渲染和计算,感兴趣的可以... 目录1. React.memo2. useMemo3. useCallback使用场景与注意事项在 Re