(1)Linux 内存管理

2020-12-09  本文已影响0人  hedgehog1112

一、Intel 处理器的发展历史

1、80386 实现页式内存管理:早期 Intel 处理器80286 用段式内存管理。发现,没页式内存管理不够,使X86系列没竞争力

2、页式作用:在段式内存映的地址上加一层地址映射

3、段式映射地址为“线性地址”(虚拟地址),不再是“物理地址”。页式 线性地址映射成物理地址。

4、X86 逻辑地址解析过程

ps:程序用逻辑地址,「段式内存管理」转换前地址

二、Linux 用什么方式管理内存

页式内存管理,涉及段机制(历史导致,既然 CPU 硬件结构这样,Linux 内核只好服从)

事实上,Linux 内核“上有政策,下有对策”:

    1)Linux 每段都从 0 地址开始的整个 4GB 虚拟空间(32 位环境下),就是段起始地址一样的。

    2)意味Linux 、操作系统代码和应用程序代码,面对地址空间都是线性地址空间(虚拟地址),屏蔽处理器中逻辑地址只被用于访问控制内存保护

三、Linux 虚拟地址空间是如何分布

1、虚拟地址内部分为内核和用户空间,不同位数系统,地址空间范围也不同。32 位和 64 位系统:

    32 位系统:内核1G,最高处,剩下3G 用户空间

    64 位系统:内核和用户空间都是 128T,分别最高/低处,中间未定义

2、内核与用户空间的区别:

    进程在用户态时,只能访问用户空间内存;

    进入内核态后,才可访问内核空间内存;    因为进程每个虚拟内存中的内核地址,关联相同物理内存

每个内核空间都一致

3、虚拟空间的划分(32 位系统用户空间)

用户空间内存,低到高7 种不同内存段:

    1)程序文件段:二进制可执行代码;

    2)已初始化数据段:静态常量;

    3)未初始化数据段:未初始化的静态变量;

    4)堆段:动态分配的内存,低地址向上增长

    5)文件映射段:动态库、共享内存等,低地址开始向上增长(跟硬件和内核版本有关)

    6)栈段:局部变量和函数调用的上下文等。栈大小是固定(一般8 MB)。系统也提供参数,以便自定义大小;

ps:4堆和5文件映射段的内存是动态分配。如,C 标准库malloc() 或mmap() ,分别在堆和文件映射段动态分配内存。

总总结结

1、进程之的内存地址相互隔离,为每进程分配虚拟地址空间,程序只关心自己虚拟地址就可以,实际虚拟地址都一样,但分布到物理地址内存不一样。

2、进程有自己虚拟空间,物理内存只有一个,启用大量进程,物理内存紧张,操作系统内存交换,不常使用的内存暂时存放到硬盘(换出),要时候再装回物理内存(换入)

3、虚拟地址「映射」到物理地址,分段分页的方式,两者结合

4、内存分段:栈段、堆段、数据段、代码段等连续空间。每段大小不统一,导致内存碎片和交换效率低

5、于是出现内存分页,把虚拟空间和物理空间分成大小固定的页(4KB),不会产生碎片。同时在交换时,写入硬盘一个或几个页,大大提高了内存交换效率。

6、多级页表:解决页表过大空间上问题,但导致 CPU 寻址加大时间开销(多层表参与)。于是根据局部性原理,CPU 芯片加入TLB,负责缓存最近常被访问页表项,大大提高地址转换速度。

下面是本文总结:

7、Linux 无法避免分段管理。于是把所有段的基地址设为 0,所有程序地址空间都是线性地址空间(虚拟地址),屏蔽了 CPU 逻辑地址,段只被用于访问控制和内存保护。

8、虚拟空间分为用户态内核态,用户态的分布:代码段、全局变量、BSS、函数栈、堆内存、映射区

https://mp.weixin.qq.com/s/HJB_ATQFNqG82YBCRr97CA

上一篇下一篇

猜你喜欢

热点阅读