Linux内存管理(一):内存管理概述

article/2025/10/11 13:52:02

首先明确下面几个概念:

  • 程序(Program):一组指令的有序集合,是静态的实体。
  • 进程(Process):执行程序后,操作系统将程序的可执行文件和它的相关依赖加载到内存中,得到的动态的实体称为进程。

程序和进程并不是一一对应的。一段程序可以在不同的数据集上形成多个不同的进程,也可以因为没被执行而不产生进程。但进程一定有一段对应的程序。

  • 内存(Memory):是程序运行的场所,在程序运行时存放代码、参数、中间数据的地方。

Linux系统内存管理的职责是:进程请求内存时分配可用内存,进程释放内存时回收内存,跟踪系统内存的使用情况。

一、虚拟内存与物理内存、逻辑地址与物理地址

物理内存:就是内存条提供的物理存储空间,主板上的内存条提供多大的存储空间,物理内存就有多大。

物理地址:内存条中的存储单元的真实地址,编号从0开始一直到物理存储单元的最高端。

早期的操作系统没有虚拟内存概念的时候,程序寻址都使用物理地址。在32位平台下,CPU的寻址范围是2^32也就是0~4G。对于多个进程并发执行的操作系统,如果为每个进程都分配4G的物理内存,会产生很多问题,例如

1.物理内存是有限的,不足以为每个进程都提供4G的运行空间,没分配到空间的进程只能在内存外等待,十分没有效率。
2.由于每个程序都使用物理地址进行访问,相互没有隔离,导致一个进程可以通过物理地址直接修改另一个进程的数据,十分不安全
3.由于每次程序运行时被装入内存的位置是不固定的,但程序中物理地址是写死的,因此访问不到正确的数据。

为了解决上述问题,虚拟内存应运而生。

虚拟内存:在系统中,每个进程都认为自己得到了4G连续的地址空间。实际上这份空间并不是真正的内存空间,它通常被分割成很多各物理内存碎片,乱序的存放在物理内存条中,甚至有一些因为内存有限只能存放在磁盘存储器上,在必要时再被装入内存。

逻辑地址:现代程序内部使用的地址都是逻辑地址,也就是数据在进程的4G虚拟内存中的地址。逻辑地址当然也是虚拟的。

所有进程共享同一块物理内存,逻辑上各自拥有一块连续的虚拟内存。当一个进程要访问某个数据时,会给出该数据的逻辑地址。系统使用地址映射算法将逻辑地址转换成物理地址,再访问物理内存中相应的存储单元取得数据。

二、页式内存管理

为了方便逻辑地址到物理地址的映射,大多数操作系统都使用了页式的内存管理机制,通过页的映射来实现逻辑地址到物理地址的转换。

在页式内存管理体制中,(Page)是内存管理的基本单元。Linux中一个页的默认大小为4KB。

每个进程都有独自的虚拟内存4G,可被分成4G/4K=1M个页。将这些从0开始编号。

将物理内存也以4K为一个单位进行管理,每个单位可被称为页框,将页框也从0开始进行编号。

为每个进程都建立一张表,用来存储该进程每个页加载到物理内存的哪个页框中,这样的表称为页表。页表中的每一项都是页到页框的映射,称为页表项

三、虚拟内存空间划分、用户空间和内核空间

每个进程有4G的虚拟内存,通常将0~3G划分为用户空间,3 ~ 4G划分为内核空间

用户进程可以直接访问用户空间,每个进程都有自己独立的用户空间。

用户进程不能直接访问内核空间,通过系统调用或异常操作才能访问内核空间。所有进程共享内核空间。

一个进程的虚拟内存可以大致进行如下划分:
注意:这是一个大致的划分,实际上Linux划分得更细

用户空间被大致划分为代码段、数据段、BSS段、堆段、栈段这五个段,每个段得作用如下:

  • 代码段(Code segment):存放可执行代码,二进制机器指令形式,只读。
  • 数据段(Data segment):存放已初始化的数据,即赋初值的全局变量和static变量。
  • BSS段:存放未初始化的数据,即没有赋初值的全局变量和static变量。
  • 堆段(heap):动态分配的内存空间,即malloc()函数申请的空间,向高地址增长。
  • mmap段:程序员主动调用mmap()函数时才会生成的一个段,用来存储内存映射的内容,也就是将内核空间的一段内存映射到用户空间。由于内存映射的段的大小也是不确定的,存在与stack段、heap段碰撞的可能,为了避免碰撞,将该段的首地址选择在TASK_SIZE / 3处(即1GB处),且向高地址增长。
  • 栈段(stack):函数内的局部变量、形参和返回值临时存储的内存空间,向低地址增长。

内核空间被大致分为ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM三个区域,每个区域的作用如下:

  • ZONE_DMA:范围为0MB~16MB,称为DMA内存区。该区域的物理页面专门供I/O设备的DMA使用。之所以需要单独管理DMA的物理页面,是因为DMA使用物理地址访问内存,不经过MMU,并且需要连续的缓冲区,所以为了能够提供物理上连续的缓冲区,必须从物理地址空间专门划分一段区域用于DMA。
  • ZONE_NORMAL:范围为16MB~896MB,称为低端内存区。该区域直接线性映射到物理内存空间中。ZONE_NORMAL内存不够时,Linux也会去ZONE_DMA申请,但反之则不可。
  • ZONE_HIGHMEM:范围为896MB~1GB,称为高端内存区。该区域使用非线性映射对应到物理空间上,因此在该区域内寻址需要借助页表来完成。非线性区不会提前进行内存映射,而是在使用时动态映射。ZONE_HIGHMEM不够时,Linux也会去ZONE_NORMAL内存区申请,但反之则不可。

vmalloc()函数使用的是ZONE_HIGHMEM的空间,通常用来申请大块的内存空间,且逻辑地址连续的空间物理地址不一定连续。kmalloc()函数使用ZONE_NORMAL中的空间,可以以字节为单位进行分配,通常用来申请小块的内存空间,且逻辑地址连续的物理地址一定连续。


http://chatgpt.dhexx.cn/article/ROUZdNIS.shtml

相关文章

史上最全linux内存管理

Linux内存结构 Node 首先, 内存被划分为结点. 每个结点关联到系统中的一个处理器,内核中表示为pg_data_t的 实例. 系统中每个节点被链接到一个以NULL结尾的pgdat_list链表中<而其中的每个节点利用pg_data_tnode_next字段链接到下一节&#xff0e;而对于PC这种UMA结构的机…

一文掌握 Linux 内存管理

作者&#xff1a;dengxuanshi&#xff0c;腾讯 IEG 后台开发工程师 以下源代码来自 linux-5.10.3 内核代码&#xff0c;主要以 x86-32 为例。 Linux 内存管理是一个很复杂的“工程”&#xff0c;它不仅仅是对物理内存的管理&#xff0c;也涉及到虚拟内存管理、内存交换和内存回…

linux内存管理(一)-内存管理架构

文章目录 一、内存管理架构二、虚拟地址空间布局架构2.1内核地址空间布局2.2用户地址空间布局 三、物理内存体系架构3.1 正常内存3.2 设备内存四、内存结构五、内存模型六、虚拟地址和物理地址的转换七、页表八、内存映射原理分析 一、内存管理架构 内存管理子系统架构可以分为…

Linux内存管理(最透彻的一篇)

【转】Linux内存管理&#xff08;最透彻的一篇&#xff09; 摘要&#xff1a;本章首先以应用程序开发者的角度审视Linux的进程内存管理&#xff0c;在此基础上逐步深入到内核中讨论系统物理内存管理和内核内存的使用方法。力求从外到内、水到渠成地引导网友分析Linux的内存管…

Linux内存管理机制(最透彻的一篇)

摘要&#xff1a;本章首先以应用程序开发者的角度审视Linux的进程内存管理&#xff0c;在此基础上逐步深入到内核中讨论系统物理内存管理和内核内存的使用方法。力求从外到内、水到渠成地引导网友分析Linux的内存管理与使用。在本章最后&#xff0c;我们给出一个内存映射的实例…

概述 - Linux内存管理(一)

内存管理是从单板上电运行uboot启动引导linux并完成文件系统挂载&#xff08;文件系统管理Nandflash&#xff09;过程前两个环节都需要完成的重要工作&#xff0c;并且随着程序推进的内存管理也逐渐完善起来。如果一步到位直接编写一个非常完整的内存管理系统&#xff0c;这个过…

linux 内存管理

目录 1 Linux内存管理概述 1.1 内存的层次结构 1.2 虚拟内存概述 1.2.1 虚拟内存基本思想 1.2.2 进程虚拟地址空间 1.3 内核空间到物理空间的映射 1.3.1 内核空间的线性映射 1.3.2 内核镜像的物理存储 1.4 虚拟内存实现机制 2 进程用户空间管理 2.1 进程用户空间布局…

linux内存管理

内存管理 一、相关概念 ● 虚拟内存&#xff1a;内存管理的一种技术&#xff0c;它使得应用程序认为它拥有连续的可用内存&#xff08;一个连续完整的地址空间&#xff09;&#xff1b; ● 物理内存&#xff1a;相对于虚拟内存而言&#xff0c;指通过物理内存条而获得的内存空间…

Linux中内存管理详解

Linux中内存管理 内存管理的主要工作就是对物理内存进行组织&#xff0c;然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。 虚拟地址的作用 如果用户进程直接操作物理地址会有以下的坏处&#xff1a; 1、 用户进程可以直接操作内核对应的内存&#xff0c;破坏内…

Linux 内存管理 详解(虚拟内存、物理内存,进程地址空间)

Linux -操作系统内存管理 存储系统存储器的层次结构 Linux的内存管理物理内存物理内存管理 虚拟内存虚拟地址空间(写时拷贝) 和物理地址映射关系页表虚拟内存优缺点 「在 4GB 物理内存的机器上&#xff0c;申请 8G 内存会怎么样&#xff1f;」 计算机硬件的五大组成部分为&…

逆向汇编与反汇编——汇编基础快速入门

一、常用32位寄存器介绍 不同位数的寄存器的名称&#xff1a; eax&#xff1a;累加寄存器。通常用于算数运算&#xff0c;将结果保留在eax当中&#xff0c;当然也可以用于其他用途&#xff0c;比如一般把返回值通过eax传递出去。 ebx&#xff1a;基址寄存器 。有点类似于ebp…

汇编语言(四)——编程语法入门

目录 0.第一个汇编程序 1.语言常量 &#xff08;1&#xff09;整数常量 &#xff08;2&#xff09;实数常量 &#xff08;3&#xff09;字符常量 2.保留字 3.标识符 4.伪指令 5.指令 &#xff08;1&#xff09;标号 &#xff08;2) 指令助记符 &#xff08;3&#…

汇编语言轻松入门

​通常说的学习编程其实就是学习高级语言编程&#xff0c;比如C语言、C语言、Python语言、JAVA语言等等&#xff0c;即那些为人类设计的计算机语言。 但是&#xff0c;我们的计算机它并不理解什么是高级语言&#xff0c;计算机只是一个机器&#xff0c;它只有电气的特性&#…

汇编入门(一)

汇编入门&#xff08;一&#xff09; 1.第一个汇编程序 目前利用的是keil软件&#xff0c;建立文件时扩展名一定要为asm 如何查看具体地址存储器中的值&#xff1a; 在工具栏上选择“VIEW”>“memory windows”>“memory1” 然后输入地址即可&#xff1a; 注意这里…

汇编语言入门--调试工具debug的使用(史上最全,11种常见命令)

汇编语言入门–调试工具debug的使用&#xff08;史上最全&#xff0c;11种常见命令&#xff09; 1.直接启动debug程序 详见&#xff1a;https://bingshuai.blog.csdn.net/article/details/119978461 2.检查和修改寄存器内容命令R 检查 -r 修改 这里用AX来举例&#xff1a; -…

汇编语言入门(二)

汇编语言入门&#xff08;一&#xff09; 文章目录 寄存器【内存访问】内存中字的存储DS和【address】字的传送mov、add、sub指令数据段栈栈顶越界的问题PUSH和POP指令栈的综述栈段【栈的综述】 寄存器【内存访问】 内存中字的存储 4E20是两个字节构成一个字。 上图中0地址单…

汇编语言学习入门+亲自实操+图形并茂

汇编器 汇编器是将汇编语言转化为机器码的程序。或许你会以为汇编转化到机器码没什么大不了的&#xff0c;毕竟几乎是一对一的转换。但nasm存在的意义在于它可以很好的适应多种处理器平台&#xff0c;让编写汇编这件事都变得可移植了。nasm可以在Ubuntu下汇编&#xff0c;使用…

ARM 汇编语言入门

[翻译]二进制漏洞利用(二)ARM32位汇编下的TCP Bind shell&#xff1a;https://bbs.pediy.com/thread-253511.htm ARM汇编语言入门 From&#xff1a;ARM汇编语言入门(一)&#xff1a;https://zhuanlan.zhihu.com/p/109057983 原文地址&#xff1a;https://azeria-labs.com/writi…

基础汇编语言编程

目录 什么是汇编语言&#xff1f; 工程搭建 新建工程 环境设置 测试是否成功 正式学习汇编语言 数据处理指令 填充&#xff0c;加&#xff0c;减&#xff0c;乘 思考&#xff1a;我们可以看到R0寄存器可以存放8位十六进制数&#xff0c;那么0x12345678能不能用mov存入&am…

汇编入门学习

学自狂神&#xff1a;最通俗易懂的计算机底层教学&#xff0c;二进制到汇编学习&#xff01; 1、概述 学习路线&#xff1a; 语言 进制 进制如何运算 二进制 数据宽度 有符号数和无符号数 原码反码补码 位运算 位运算计算 汇编 寄存器 内存 汇编指令 内存复制 …