首页 > 系统相关 >Linux 内存管理

Linux 内存管理

时间:2022-10-26 21:33:05浏览次数:70  
标签:映射 管理 地址 内核 Linux 空间 内存

Linux 操作系统采用了哪种方式来管理内存呢?


在回答这个问题前,我们得先看看 Intel 处理器的发展历史。

早期 Intel 的处理器从 80286 开始使用的是段式内存管理。但是很快发现,光有段式内存管理而没有页式内存管理是不够的,这会使它的 X86 系列会失去市场的竞争力。因此,在不久以后的 80386 中就实现了页式内存管理。也就是说,80386 除了完成并完善从 80286 开始的段式内存管理的同时还实现了页式内存管理。

但是这个 80386 的页式内存管理设计时,没有绕开段式内存管理,而是建立在段式内存管理的基础上,这就意味着,页式内存管理的作用是在由段式内存管理所映射而成的地址上再加上一层地址映射。

由于此时由段式内存管理映射而成的地址不再是“物理地址”了,Intel 就称之为“线性地址”(也称虚拟地址)。于是,段式内存管理先将逻辑地址映射成线性地址,然后再由页式内存管理将线性地址映射成物理地址。

Linux 内存管理_linux

这里说明下逻辑地址和线性地址:

  • 程序所使用的地址,通常是没被段式内存管理映射的地址,称为逻辑地址;
  • 通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址;

逻辑地址是「段式内存管理」转换前的地址,线性地址则是「页式内存管理」转换前的地址。

了解完 Intel 处理器的发展历史后,我们再来说说 Linux 采用了什么方式管理内存?

Linux 内存主要采用的是页式内存管理,但同时也不可避免地涉及了段机制

这主要是上面 Intel 处理器发展历史导致的,因为 Intel X86 CPU 一律对程序中使用的地址先进行段式映射,然后才能进行页式映射。既然 CPU 的硬件结构是这样,Linux 内核也只好服从 Intel 的选择。

但是事实上,Linux 内核所采取的办法是使段式映射的过程实际上不起什么作用。也就是说,“上有政策,下有对策”,若惹不起就躲着走。

Linux 系统中的每个段都是从 0 地址开始的整个 4GB 虚拟空间(32 位环境下),也就是所有的段的起始地址都是一样的。这意味着,Linux 系统中的代码,包括操作系统本身的代码和应用程序代码,所面对的地址空间都是线性地址空间(虚拟地址),这种做法相当于屏蔽了处理器中的逻辑地址概念,段只被用于访问控制和内存保护。

我们再来瞧一瞧,Linux 的虚拟地址空间是如何分布的?

在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的系统,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,如下所示:

通过这里可以看出:

  • ​32​​ 位系统的内核空间占用​​1G​​,位于最高处,剩下的​​3G​​ 是用户空间;
  • ​64​​ 位系统的内核空间和用户空间都是​​128T​​,分别占据整个内存空间的最高和最低处,剩下的中间部分是未定义的。

再来说说,内核空间与用户空间的区别:

  • 进程在用户态时,只能访问用户空间内存;
  • 只有进入内核态后,才可以访问内核空间的内存;

虽然每个进程都各自有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存。

Linux 内存管理_内核空间_02

接下来,进一步了解虚拟空间的划分情况,用户空间和内核空间划分的方式是不同的,内核空间的分布情况就不多说了。

我们看看用户空间分布的情况,以 32 位系统为例,我画了一张图来表示它们的关系:

Linux 内存管理_内存管理_03

通过这张图你可以看到,用户空间内存,从低到高分别是 6 种不同的内存段:

  • 程序文件段(.text),包括二进制可执行代码;
  • 已初始化数据段(.data),包括静态常量;
  • 未初始化数据段(.bss),包括未初始化的静态变量;
  • 堆段,包括动态分配的内存,从低地址开始向上增长;
  • 文件映射段,包括动态库、共享内存等,从低地址开始向上增长(​​跟硬件和内核版本有关 (opens new window)​​);
  • 栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是​​8 MB​​。当然系统也提供了参数,以便我们自定义大小;

在这 7 个内存段中,堆和文件映射段的内存是动态分配的。比如说,使用 C 标准库的 ​​malloc()​​ 或者 ​​mmap()​​ ,就可以分别在堆和文件映射段动态分配内存。

标签:映射,管理,地址,内核,Linux,空间,内存
From: https://blog.51cto.com/u_10630401/5798587

相关文章

  • 内存总结
    为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都......
  • 内存满了,会发生什么?
    1、内存分配的过程是怎样的?应用程序通过malloc函数(全称是memoryallocation,中文叫动态内存分配)申请内存的时候,实际上申请的是虚拟内存,此时并不会分配物理内存。当应用程序......
  • 计算中文在内存占用的字节数
    #include<iostream>usingnamespacestd;voidmain(){ //功能:计算中文在内存占用的字节数 charname[]="成都"; charnode_name[]="成都移动04节点"; co......
  • linux虚拟机更改网关——长久生效
    1:cd /etc/sysconfig/network-scripts 2:备份原有网关文件,本机为ifcfg-ens33  3:ping一下空的地址,如图中的192.168.254.144,确认IP没被占用  4:确认网关,并更改......
  • Linux LVS-NAT模式的实现
    结构图:环境准备lvs[root@lvs~]#cat/etc/sysconfig/network-scripts/ifcfg-eth0TYPE=EthernetBOOTPROTO=noneNAME=eth0DEVICE=eth0ONBOOT=yesIPADDR=10.0.0.8......
  • 《Unix/Linux系统编程》第六章学习笔记 20201209戴骏
    信号和信号处理1.信号和中断中断:从I/O设备或协处理器发送到CPU的外部请求,它将CPU从正常执行转移到中断处理。信号:发送给进程的请求,将进程从正常执行转移到中断处理。......
  • linux查询当前时间
    查询当前时间echo$(date)查询当前日期,m为月,d为天,注意date后面有一个空格echo$(date+%Y-%m-%d)格式化输出日期+时分秒echo$(date"+%Y-%m-%d%H:%M:%S")......
  • Linux基础网络设置
    拓扑图:推荐步骤:Ø 根据拓扑给Centos01配置静态IP地址,设置默认网关和首选备用IP地址,安装DHCP服务Ø 配置修改DHCP配置指定下发IP地址范围,默认网关、首选和备份用DNS,配置......
  • linux 中 如何统计某一目录下一类文件总的大小
     001、[root@pc1test]#lsa.csva.txtb.csvb.txtc.csv[root@pc1test]#ll-h##测试文件total430M-rw-r--r--.1rootroot......
  • kali(安全)-远程获取windows电脑管理员权限实验
    1、实验环境:vmware ​ 安装vmware16软件(一直下一步就行):如果需要输入激活码,跳过即可 cn_windows_7_ultimate_x64_dvd_x15-66043.iso(靶机系统) kali-linux-2020.4-......