您的位置首页>企业动态>

Linux的内存寻址方式有哪些?

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Linux的内存寻址方式有哪些?问题。为什么是内存管理:早期的程序都是直接在物理地

音频解说

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解Linux的内存寻址方式有哪些?问题。

为什么是内存管理:

早期的程序都是直接在物理地址上运行的,也就是说这个程序需要的空间不会超过这个机器的物理内存,所以不会有问题。但是在实际场景中,它是多任务多进程的,这个为每个进程预留的物理地址是不可靠的。举个栗子:如果有A、B、C、A三个程序需要10M,B需要100M,C需要20M,总内存是120M。按照之前的分配方式,前10M给A,10M-110M给B,系统还剩10M,但是C需要20M,所以显然剩余内存不够C用,怎么办?

1.效率问题

你可能会想,C程序运行的时候,先把B程序的数据写到磁盘上,然后B程序运行的时候再把数据从磁盘上写回来,且不说B、C程序并行运行的需求无法满足,就连频繁io操作带来的耗时问题都让人无法接受。

2.流程解决隔离问题

除了效率问题,如果一个进程需要被其他进程访问,那么为它保留的空间将会崩溃。比如进程A访问的空间是前10M,但是如果程序A中的一段代码访问了10-110M,可能会导致程序B崩溃,所以进程的地址空间需要相互隔离。

3.搬迁问题

实际上,单个任务不可能在分割的内存中运行。当多个任务并行运行时,在动态申请内存释放时,可以在其他进程中申请地址。此时,有必要重新安置到新的地址。

内存管理无非是想解决以上三个问题。如何提高内存使用效率?如何隔离进程的地址空间?程序运行时如何解决重定位问题?

管理内存如何从虚拟地址映射到物理地址:

管理从虚拟地址到物理地址的内存映射的过程就是解决上述三个问题的过程。内存管理采用分段机制和分页机制分别解决了上述三个问题。大致过程如下:

分割机制:

只要程序被分成段,并且整个段被翻译到任何位置,段中的地址相对于段基址是恒定的。不管段基址是多少,只要给定段中的偏移地址,cpu就能访问正确的指令。因此,在加载用户程序时,只要将整个段内容复制到新的位置,然后将段基址寄存器中的地址更改为该地址,程序就可以准确运行,因为段中的偏移地址在程序中使用,并且偏移地址处的内容仍然与新的段基址相同。

可以看出,分段机制解决了进程间隔离和重定位的问题。这个动作是在硬件中完成的,但是有些硬件没有分段机制。作为一款跨平台的linux,它采用了更通用的分页机制,解决了从线性地址到虚拟地址再到物理地址的转换。

分页机制:

可以参考《CPU是如何访问内存的?》了解一级页表的概念。为了兼容32位和64位,linux通常采用四级页表、页全局目录、页父目录、页中间目录和页表:

这里不详细解释linux如何通过四级页表将线性地址(虚拟地址)转换为物理地址。

进程切换时,根据task_struct找到mm_struct中的pgd字段,获取新进程的页面全局目录,然后填充到CR3寄存器中,从而完成页面切换。

查看mmu分页寻址的过程:

上传代码:

可以看到,虚拟地址ffff99b488d48000对应的物理地址是80000000c8d48000。这个过程也是mmu的过程。负责编辑:CC

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。