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

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

Linux之软件包管理器yum详解

《Linux之软件包管理器yum详解》文章介绍了现代类Unix操作系统中软件包管理和包存储库的工作原理,以及如何使用包管理器如yum来安装、更新和卸载软件,文章还介绍了如何配置yum源,更新系统软件包... 目录软件包yumyum语法yum常用命令yum源配置文件介绍更新yum源查看已经安装软件的方法总结软

linux报错INFO:task xxxxxx:634 blocked for more than 120 seconds.三种解决方式

《linux报错INFO:taskxxxxxx:634blockedformorethan120seconds.三种解决方式》文章描述了一个Linux最小系统运行时出现的“hung_ta... 目录1.问题描述2.解决办法2.1 缩小文件系统缓存大小2.2 修改系统IO调度策略2.3 取消120秒时间限制3

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux

Linux:alias如何设置永久生效

《Linux:alias如何设置永久生效》在Linux中设置别名永久生效的步骤包括:在/root/.bashrc文件中配置别名,保存并退出,然后使用source命令(或点命令)使配置立即生效,这样,别... 目录linux:alias设置永久生效步骤保存退出后功能总结Linux:alias设置永久生效步骤

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存