推广 热搜: 广告  优化  服务  百度  项目  排名    账号  设备  系统 

【内存】Linux 页表、大页与透明大页|大页内存

   日期:2024-12-24     作者:x5bnw    caijiyuan  
核心提示:目录页表与MMUCPU访问的是什么地址(虚拟地址,物理地址)?MMU如何工作MMU对内存的保护多级页表一、 内存映射与页表1. 内存映射2.

目录

【内存】Linux 页表、大页与透明大页|大页内存

页表与MMU

CPU访问的是什么地址(虚拟地址,物理地址)?

MMU如何工作

MMU对内存的保护

多级页表

一、 内存映射与页表

1. 内存映射

2. 页表

4. 页表的简单工作原理

大页

什么是大内存页huge page?

为什么使用“大内存页”?

1. 大页的优点

2. 大页的缺点

大内存页适用范围

3. 大页的分配方法

三、 透明大页

1. 查看是否启用

2. 关闭透明大页

使用大页实例

查看缺页中断统计


作者:bandaoyu 链接:https://blog.csdn.net/bandaoyu/article/details/113352282

其实CPU根本不关心它访问的是物理地址还是虚拟地址,它只访问一个地址,然后从数据线上获取数据。


启用MMU时,CPU访问地址是向MMU发送地址,然后从MMU获得数据,虚拟地址经过MMU转化为物理地址,从而访问外部内存里的数据。


禁用MMU时,CPU访问物理地址。

映射.png

页表:就是记录虚拟地址到物理地址映射规则的集合。

内存以4K为单位分成一块一块的,页表记录每一块物理内存的首地址和虚拟地址的映射关系,即只需记录上图中0xC00F3000和0xF3000之间的映射即可。

MMU是如何将虚拟地址转化为物理地址呢,它会去查询页表。
也就是说,MMU将虚拟地址转换为物理地址,不是按一个一个地址转换的,是以4k一页为单位转换的。

MMU中有几个概念:
PTE:页表项,即某条具体的转换规则,例如0x84050000这一页映射到0x8000物理页。
TLB:MMU中的cache,用来缓存最近用过的PTE

mmu的pte转换时按照4k大小的页为单位,32bit有12个bit是用不上的,在这些bit中设置访问权限的属性,如禁止访问、可读、可写和可执行等。

4K(12bit)为单位的MMU映射意味着,需要2^20 个条目用来映射4G空间,即占用4M内存(32bit=4byte*2^20 =4byte*1M=4M)。

每个进程的页表都是不同的(前3G映射不同,后1G相同),所以切换进程时候会将该进程的页表地址写进MMU中,从而更新整个MMU的映射规则。

为了解决页表项过多的问题,Linux 提供了两种机制,也就是多级页表和大页(HugePage),后面我们以大页为重点。

从上面可以看出,因为各个进程映射不同,每个进程必须有独立的页表。

系统中如果有100个进程,则需要4*100=400M内存来存储页表,这是不行的。那么能不能不映射一些页呢? 不行,4G的空间哪些不用是未知的,所以必须提前都预留映射。

假如一个进程需要使用100M的内存,那么1M个页表项中只有25k个是有用的,使用率百分之二,剩下的3.98M页表内存都浪费掉了。

想要节省页表内存,就不能以4K为单位映射,要以4M为单位映射,页表只需要1K个,占用4K内存。每一个页表项指向4M的地址,需要第二级页表,第二级页表按照4k为单位映射的话,每个4M需要1k个页表项,占用4k内存。再算算上述一个进程需要100M内存,首先一级页表是4K,二级页表只需要25张*4k,全部页表只占用104k内存,相比4M节省了大部分内存,仅浪费了3.99K的内存。

可以看到,使用多级页表,不仅节省每个进程的页表占用的内存,还能根据进程使用内存不同动态的调整页表占用内存的大小。

下面是一个虚拟地址0x3213 2160通过二级页表映射到物理地址的过程

事实上,在ARM架构中,这个访问过程是硬件实现的,但是页表的填充是软件维护的

image.png

彩蛋:说到MMU,有个问题:为什么Uboot要关掉mmu?
kernel启动对环境是由要求的,关掉mmu,关掉dcache,icache无所谓

待学习 - 收藏夹 - 知乎

1. 内存映射

我们通常所说的内存容量,指的是物理内存,只有内核才可以直接访问物理内存,进程并不可以。

Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。

虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。比如最常见的 32 位和64 位系统:

既然每个进程都有一个这么大的地址空间,那么所有进程的虚拟内存加起来,自然要比实际的物理内存大得多。所以,并不是所有的虚拟内存都会分配物理内存,只有那些实际使用的虚拟内存才分配物理内存,并且分配后的物理内存,是通过内存映射来管理的。内存映射,其实就是将虚拟内存地址映射到物理内存地址。


2. 页表

为了完成内存映射,内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系,如下图所示:

页的大小只有 4 KB ,导致的另一个问题就是,当物理内存很大时,页表会变得非常大,占用大量物理内存。

4. 页表的简单工作原理

下图是比较简单情况下的示意图,用于描述在32位系统下,页大小为4K时,操作系统如何为进程的虚拟地址和实际物理地址进行转换:

  • 目录表,是用于索引页表的数据结构,其中存储着目录项(共1024个、每个4B,因此目录表共4B*1024=4K ),每个目录项指向一个页表,即可以存储1024个页表。

  • 页表,用来存放物理地址页的起始地址,即页表项(也是共1024个、每个4B,因此一个页表的大小也是4K),由于目录表最多可存1024个页表,因此页表的最大大小是1024*4K=4M。

  • 页表项,每个页表项指向4K的物理内存页,因此页表一共可以指向的物理内存大小为:1024(页表数)*1024(每个页表的页表项数)*4K(一个页表项指向的物理内存大小)=4G

假如一个进程,访问的物理内存有1GB,即262144个内存页,在32位系统中,页表需要262144*4/1024/1024=1MB,而在64位系统下,页表占用的空间增加1倍,即2MB。

对于Linux系统中运行的Oracle数据库,假如数据库的SGA大小12GB,如果一个Oracle Process访问到了所有的SGA内存,其页表大小会是24MB,如果有300个左右的会话,那么这300个连接的页表会达到7200MB,只不过并不是每个进程都会访问到SGA中所有的内存。

页表大小可以通过 /proc/meminfo 的 PageTables部分查看。

Linux 页表、大页与透明大页_Hehuyi_In的博客-CSDN博客_linux 大页

“大内存页”有助于 Linux 系统进行虚拟内存管理。顾名思义,除了标准的 4KB 大小的页面外,它们还能帮助管理内存中的巨大的页面。使用“大内存页”,你最大可以定义 1GB 的页面大小。

本文地址:http://gzhdwind.xhstdz.com/xwnews/685.html    物流园资讯网 http://gzhdwind.xhstdz.com/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

 
 
更多>同类生活信息

文章列表
相关文章
最新动态
推荐图文
生活信息
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号