深度详解linux内存管理

前言 总结送福利

内存管理一向是所有操作系统书籍不惜笔墨重点讨论的内容,无论市面上或是网上都充斥着大量涉及内存管理的教材和资料。因此,我们这里所要写的Linux内存管理采取避重就轻的策略,从理论层面就不去班门弄斧,贻笑大方了。我们最想做的和可能做到的是从开发者的角度谈谈对内存管理的理解,最终目的是把我们在内核开发中使用内存的经验和对Linux内存管理的认识与大家共享

目录

深度详解Linux内存管理(MM)机制

1、X86分段及分页管理机制

2、内存管理源码分析

x86-16分段管理的区别

Intel对分段内存管理逻辑地址的定义是【段号+段内地址】。在x86-16体系的分段管理中,CPU给出的内存地址是16位的段内偏移地址,段的基址从段寄存器中获得,最后计算出24位的物理地址。 而在IA-32体系中引入了保护模式,每个进程有4G的独立地址空间,CPU直接给出的是32位的段内偏移地址,段的基址从内存中获得,最后计算出32为的物理地址。他们最大的不同就在于获取基址的方式以及计算方法。

深度详解Linux内存管理(MM)机制

IA-32为了保持向前兼容,保留了CS/DS/ES/SS这4个寄存器,但因为不在从段寄存器中获得段价值,这4个段寄存器实际上已经失去了原本的作用(但不代表没有使用)。IA-32在内存中使用一张段表来记录各个段映射的物理内存地址(如下图)

深度详解Linux内存管理(MM)机制

在译地的过程中,x86-16是通过16位的段基址和16位的段内偏移不是简单的相加,而是通过 段值*0x10 + 偏移地址 对基址重定向的方式计算得到物理地址,而IA-32中则相对简单,不需要对基址重定向,这一点和前面分页内存管理是相似的。而CPU只需要为这个段表提供一个记录其首地址的寄存器就可以了。 同样也可以使用TLB来加速。

深度详解Linux内存管理(MM)机制

与x86-16中分段管理另一个不同是,在IA-32中,因为有了独立的地址空间,对多程序也支持的非常好。而分段可以很好的支持进程间数据的共享。

深度详解Linux内存管理(MM)机制

分段内存管理

为什么分段?

在x86-16体系中,为了解决16位寄存器对20位地址线的寻址问题,引入了分段式内存管理。而CPU则使用CS,DS,ES,SS等寄存器来保存程序的段首地址。当CPU执行指令需要访问内存时,只会送出段内的偏移地址,而通过指令的类型类确定访问那一个段寄存器。具体可以参考:计算机原理学习(5)– x86-16 CPU和内存管理

到了IA-32,Intel引入了保护模式,所以在IA-32中为了保持兼容性,所以同样支持内存分段管理。另外我们讨论过了内存分页,页面中包含了程序的代码,数据等信息,它们都有各自的地址。这些地址是在编译的时候就确定的,因为每个进程都有独立完整的内存空间,只需要把页和物理页映射就能运行,所以这个地址是可以在编译时就决定的。在编译时,编译器会等程序进行语法词法等分析,在编译过程中会建立许多的表,来确定代码和变量的虚拟地址:

  • 被保存起来供打印清单的源程序正文;
  • 符号表,包含变量的名字和属性;
  • 包含所有用到的整形和浮点型数据的表;
  • 语法分析树,包括程序语法分析的结果;
  • 编译器内部过程调用的堆栈。

前面4张表会随着编译的进行不断增大,而堆栈的数据也会变化,现在的问题就是,每一张表的大小都不确定,那么如何指定每一张表在虚拟内存空间的地址呢?

深度详解Linux内存管理(MM)机制

如上图,没一张表都有自己的起始地址,但是当变量很多的时候,符号表需要的空间可能会超过程序正文的起始地址,这个时候就会把源程序的表的地址覆盖掉。当然编译器没有这么傻,它可以提示无法继续编译,当然这样并不合适,另一个办法就是拿出一部分没有使用的空间给符号表。造成这个问题的原因就是分页系统中的虚拟地址是一维的,所以在编译过程中必须给变量,代码分配虚拟地址。这个有点类似没有采用分页之前,进程之间使用物理地址导致相互覆盖的问题。

深度详解Linux内存管理(MM)机制

所以我们可以为不同的表分配自己的空间地址,也就是分段,这样他们地址都是相对地址,全部编译完成后确定了每张表的大小,就可以计算出实际的虚拟地址了。

分段的作用

总结

分页实际是一个纯粹逻辑上的概念,因为实际的程序和内存并没有被真正的分为了不同的页面。而分段则不同,他是一个逻辑实体。一个段中可以是变量,源代码或者堆栈。一般来说每个段中不会包含不同类型的内容。而分段主要有以下几个作用:

需要C/C++ Linux服务器架构师学习资料后台私信“资料”(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等等。。。),免费分享

原创文章,作者:芒小种,如若转载,请注明出处:http://www.fhgg.net/shenghuobaike/53497.html

本文来自投稿,不代表【食趣网】立场,如若转载,请注明出处:http://www.fhgg.net/

(0)
上一篇 2023年4月5日 上午10:58
下一篇 2023年4月5日 上午10:59

相关推荐

发表回复

登录后才能评论