找回密码
 立即注册
  • QQ空间
  • 回复
  • 收藏

linux内存管理初步介绍

泡泡龙| 2019-2-23 21:13 阅读 676 评论 0

内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。linux内核知识有两个大难点也是核心,一个是内存,一个进程,如果把这两大块内容学透,理解了内存和进程,对所有软件开发的理解都会有了全局观那对于linux内核来说基本上算是高手了。

1、内存是什么?

1)内存又称主存,是 CPU 能直接寻址的存储空间,由半导体器件制成

2)内存的特点是存取速率快

2、内存的作用

1)暂时存放 cpu 的运算数据

2)硬盘等外部存储器交换的数据

3)保障 cpu 计算的稳定性和高性能

二、 linux 内存地址空间

1、linux 内存地址空间 Linux 内存管理全貌

2、内存地址——用户态&内核态

· 用户态:Ring3 运行于用户态的代码使用的内存。

· 内核态:Ring0 在处理器的存储保护中,核心态。

· 用户态切换到内核态的 3 种方式:系统调用、异常、外设中断

· 区别:每个进程都有完全属于自己的,独立的,不被干扰的内存空间;用户态的程序就不能随意操作内核地址空间,具有一定的安全保护作用;内核态线程共享内核地址空间;

3、内存地址——MMU 地址转换

· MMU 是一种硬件电路,它包含两个部件,一个是分段部件,一个是分页部件

· 分段机制把一个逻辑地址转换为线性地址

· 分页机制把一个线性地址转换为物理地址

4、内存地址——分段机制

1) 段选择符

· 为了方便快速检索段选择符,处理器提供了 6 个分段寄存器来缓存段选择符,它们是: cs,ss,ds,es,fs 和 gs

· 段的基地址(Base Address):在线性地址空间中段的起始地址

· 段的界限(Limit):在虚拟地址空间中,段内可以使用的最大偏移量

2) 分段实现

· 逻辑地址的段寄存器中的值提供段描述符,然后从段描述符中得到段基址和段界限,然后加上逻辑地址的偏移量,就得到了线性地址

5、内存地址——分页机制(32 位)

· 分页机制是在分段机制之后进行的,它进一步将线性地址转换为物理地址

· 10 位页目录,10 位页表项, 12 位页偏移地址

· 单页的大小为 4KB

6、用户态地址空间

· TEXT:代码段可执行代码、字符串字面值、只读变量

· DATA:数据段,映射程序中已经初始化的全局变量

· BSS 段:存放程序中未初始化的全局变量

· HEAP:运行时的堆,在程序运行中使用 malloc 申请的内存区域

· MMAP:共享库及匿名文件的映射区域

· STACK:用户进程栈

用户态一个进程有一个task_struct的结构体描述,每个进程的地址空间都有一个mm_struct描述,如下图task_struct中的mm指针指向mm_struct中的mmp然后指向vm_area_struct结构体,vm_area_struct链表的每一个节点就代表进程的一个虚拟地址空间,即一个VMA,一个VMA最终可能对应ELF可执行程序的数据段、代码段、堆、栈、或者动态链接库的某个部分,mm_struct中的pgd为页表。

7、内核态地址空间

· 直接映射区:线性空间中从 3G 开始最大 896M 的区间,为直接内存映射区

· 动态内存映射区:该区域由内核函数 vmalloc 来分配

· 永久内存映射区:该区域可访问高端内存

· 固定映射区:该区域和 4G 的顶端只有 4k 的隔离带,其每个地址项都服务于特定的用途 等

8、进程内存空间

· 用户进程通常情况只能访问用户空间的虚拟地址,不能访问内核空间虚拟地址

· 内核空间是由内核负责映射,不会跟着进程变化;内核空间地址有自己对应的页表,用户进程各自有不同额页表

结束语:

本篇只是大致介绍了宏观上的内存大致情形,内存这边涉及的比较多,后面我还要从以下几个方面介绍下:

1、物理内存的区域:ZONE_DMA/ZONE_NORMAL/ZONE_HIGHMEM。

2、malloc内存原理,以及虚拟机地址如何映射到物理地址。

3、物理地址管理,改进虚拟地址到物理地址转换速度的缓存TLB。

4、三种系统架构与二种存储器访问方式(SMP和NUMA/MMP)。

后记:内存管理这方向我看了好多遍书也查了好多资料,始终不得窥见其真正内涵,前几天得一linux内核高手指导讲解。突然茅塞顿开。再回过头来看内存管理相关书籍和资料就明白很多了。所以趁热打铁把内存管理内容先记录分享出来。大家有什么想知道了解,我没提到的可以留言或者私信给我,或者我写的哪里有不妥之处也可以给我指出来(毕竟也是自己的理解)。我改正。

文章点评