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

相关文章

Linux文件名修改方法大全

《Linux文件名修改方法大全》在Linux系统中,文件名修改是一个常见且重要的操作,文件名修改可以更好地管理文件和文件夹,使其更具可读性和有序性,本文将介绍三种在Linux系统下常用的文件名修改方法... 目录一、引言二、使用mv命令修改文件名三、使用rename命令修改文件名四、mv命令和rename命

利用Python和C++解析gltf文件的示例详解

《利用Python和C++解析gltf文件的示例详解》gltf,全称是GLTransmissionFormat,是一种开放的3D文件格式,Python和C++是两个非常强大的工具,下面我们就来看看如何... 目录什么是gltf文件选择语言的原因安装必要的库解析gltf文件的步骤1. 读取gltf文件2. 提

Python解析器安装指南分享(Mac/Windows/Linux)

《Python解析器安装指南分享(Mac/Windows/Linux)》:本文主要介绍Python解析器安装指南(Mac/Windows/Linux),具有很好的参考价值,希望对大家有所帮助,如有... 目NMNkN录1js. 安装包下载1.1 python 下载官网2.核心安装方式3. MACOS 系统安

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

Linux配置IP地址的三种实现方式

《Linux配置IP地址的三种实现方式》:本文主要介绍Linux配置IP地址的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录环境RedHat9第一种安装 直接配置网卡文件第二种方式 nmcli(Networkmanager command-line

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

Linux下修改hostname的三种实现方式

《Linux下修改hostname的三种实现方式》:本文主要介绍Linux下修改hostname的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下修改ho编程stname三种方式方法1:修改配置文件方法2:hFvEWEostnamectl命

Linux虚拟机不显示IP地址的解决方法(亲测有效)

《Linux虚拟机不显示IP地址的解决方法(亲测有效)》本文主要介绍了通过VMware新装的Linux系统没有IP地址的解决方法,主要步骤包括:关闭虚拟机、打开VM虚拟网络编辑器、还原VMnet8或修... 目录前言步骤0.问题情况1.关闭虚拟机2.China编程打开VM虚拟网络编辑器3.1 方法一:点击还原VM