Linux内存管理解析(二) : 关于Linux内存管理的大体框架

2023-10-18 03:32

本文主要是介绍Linux内存管理解析(二) : 关于Linux内存管理的大体框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  什么是内存管理 ?

  首先内存管理管理的主要对象是虚拟内存,但是虚拟内存对应的映射主要为物理内存,其次也可能通过交换空间把虚拟内存与硬盘映射起来,既然如此,那我们先了解物理内存的管理。

  对于物理内存而言,首先我们需要知道的是,linux x86体系结构中内核主要处于 0 - 1G(物理地址)中。而物理内存是有限的。但我们又要为每个程序提供相互独立且连续的内存空间。正因如此我们引出了虚拟内存。

  什么是虚拟内存?

  虚拟内存 是 段寄存器:段变址寄存器 结合的结果。但是仅仅依赖这两个寄存器并不能得到什么有效的东西。要得到线性地址我们需要依赖分段机制。要得到物理地址我们需要分页机制。简而言之,虚拟地址+分段机制的映射得到线性地址,线性地址+分页机制的映射得到物理地址(实际上这个映射到物理地址都是依赖MMU(内存管理单元)来寻址的)。

  如何利用虚拟地址保证每个进程都拥有独立且连续的内存空间呢?

  在Linux中,基本上没怎么依赖分段机制来实现,主要是依赖分页机制。为什么这么说呢?因为对于除特定的进程之外各个段描述符(一个进程可以有多个段,例如代码段,数据段等)的段基址都是从0开始的(也就是说在这里 逻辑地址 = 线性地址)。

  

  至于如何利用分页机制来实现虚拟内存这个问题,就需要很长的讨论了,我们不妨简单的先概述一下:

      

    对于每个进程而言,都有4G的虚拟内存,每个进程都用 task_struct(进程描述符) 来描述,每个进程的虚拟内存都用 mm_struct(虚拟内存区域描述符) 来描述,对于每个进程而言,都有自己的页全局目录,页全局表指向一个中间页目录(页目录表),而每个页目录项指向一个页表,其实这个所谓的页全局表在x86体系结构中也就是 CR3,而修改CR3的值,就能切换整个页目录,也就达到了切换虚拟内存的作用。对于一个进程而言,并不是所有的4G虚拟地址都是在进程初始化的时候就分配,而是在进程运行时,如若需要分配才动态分配,但分配地址其实就是修改页表项,使得当前进程的虚拟地址映射到物理地址

  在linux中进程有两种形态,第一种是用户态,第二种是内核态。只有在内核态的时候才能访问内核的数据和得到某些权限(io操作权限),于是linux把虚拟内存页分为了两块 : 用户空间和内核空间。

  虚拟内存的划分(对于每个进程而言,用户空间映射的物理内存才是自己私有的内存,内核空间映射的物理内存是大家共享的):

    虚拟内存在linux中被划分为两个部分 :

    内核空间 : 虚拟内存为 3 - 4G 被作为 内核空间(内核空间几乎都是线性映射, 即 物理内存 = 虚拟内存 - 3G)

    用户空间 : 虚拟内存为 0 - 3G 被作为 用户空间

  既然内核被划分为两个部分,且内核空间和用户空间有很大的不同,于是就必须要用两种管理方式。但无论是内核空间内存管理还是用户空间内核管理,其实都是内核来管理的(用户进程对于如何管理内存是没有权限的)!区别在于是内核管理内核空间还是内核管理用户空间

    内核管理内核空间:

      我们之前说过 : 内核主要处于 0 - 1G(物理地址)中,而我们对 0 - 1G 物理内存也进行了一个分区 : 

     

 

       而 0 - 896M是内核在初始化的时候就已经映射到内核空间 3G -- 3G + 896M上了,且满足 物理内存 = 虚拟内存 - 3G。

      为什么要设立三个分区?

      ZONE_DMA : 为了兼容某些只能直接内存访问(也就是不通过MMU进行分段和分页),例如ISA设备只能访问物理内存的前16MB。

      ZONE_NORMAL : 这部分已经很早就映射了。

      ZONE_HIGHMEM : 为了解决一些体系结构(x86)物理寻址范围大于虚拟地址寻址范围(也就是多出来了物理地址)。于是采取动态映射的方式来利用一些未被映射的页。或者借助128MB高端内存地址空间访问所有物理内存(借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存)。

      

 

这篇关于Linux内存管理解析(二) : 关于Linux内存管理的大体框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图