[转帖]Linux 页表、大页与透明大页
一、 内存映射与页表
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 提供了两种机制,也就是多级页表和大页(HugePage),后面我们以大页为重点。
二、 大页
大页顾名思义,就是比较大的页,通常是2MB。由于页变大了,需要的页表项也就小了,占用物理内存也减少了。
1. 大页的优点
- 减少页表大小:默认页面大小为 4K,而大页为 2048K,意味着系统需要处理的页面减少了 512 倍。大页的页表在各进程之间可以共享,也降低了页表的大小。
- 减少页表遍历:大页覆盖更大的连续虚拟地址范围,使得CPU中的TLB(可理解为CPU对页表的CACHE)命中率大大提高,减少了遍历页表以从虚拟地址获取物理地址的次数。
- 减少页表查找开销:
- 避免swap:大页内存只能锁定在物理内存中,不可swap,因此没有page-in/page-out机制开销,避免了swap引起的性能影响。
- 减少了内存开销:由于要处理的页面数量较少,明显减少了页表访问可能出现的瓶颈。
2. 大页的缺点
- 要预先分配
- 需要重启主机生效
- 当服务器内存或SGA调整时,需要对应调整大页设置
- 如果分配不当(过多、过少、os参数配置错误),反而可能引起严重问题
严重问题可能包括:
- (绝)大部分大页内存未能使用,严重浪费内存
- 数据库性能差
- 系统内存不足或交换过多
- 数据库实例无法启动
- 关键系统服务失败
- 极高的sys cpu使用率
3. 大页的分配方法
- 检查/proc/meminfo,确认系统支持HugePage
- HugePages Total:系统中配置的大页数。
- HugePages Free:没有访问过的大页数。
- HugePages Rsvd:已经分配但是还未使用的页面数。
- Hugepagesize:大页size,这里为2MB,有的内核配置中可能为4MB。
- 设置memlock
设定oracle用户可以锁定内存的大小。这个参数在/etc/security/limits.conf文件,单位是KB。开启大页时,这个参数很重要,如果设置过小,可能导致大页无法被用到,白白浪费内存。
根据 What is Memlock and How to Calculate the Values for Memlock? (Doc ID 2511230.1) 文档建议:
- 未启用大页:至少为3G
- 启用为大页:至少设置为服务器内存的90%
- 建议大小:内存大小 > memlock大小 >= 大页总内存 > SGA
例如:
-
oracle soft memlock 18878464
-
oracle hard memlock 18878464
重新以oracle用户连接到数据库服务器,使用ulimit -a命令便可看到对应设置
- 改为AUTO方式管理SGA
对于11g,由于HugePage只能用于共享内存,不能用于PGA,所以不能使用AMM,只能分别设置SGA和PGA。SGA同样只能是AUTO方式管理,需要将SGA_TARGET_SIZE设为大于0的合适值。
- 查看建议的大页数量
到目前为止,大页只能用于共享内存段等少量类型的内存。一旦将物理内存用作大页,那么这些物理内存就不能作其他用途,比如作为进程的私有内存。因此不能将过多的内存设置为大页,通常将大页用作Oracle数据库的SGA。
Oracle Linux: Shell Script to Calculate Values Recommended Linux HugePages / HugeTLB Configuration (Doc ID 401749.1) 提供了计算建议值的脚本。需要先设置好SGA等参数、启动Oracle、并以Oracle用户执行该脚本
- 修改/etc/sysctl.conf文件,设置vm.nr_hugepages=建议值,执行sysctl –p命令
vm.nr_hugepages这个参数值为上步计算出的建议值。然后检查/proc/meminfo,如果HugePages_Total小于设置的数量,表明没有足够的连续物理内存用于这些大内存页,需要重启服务器。
- 重启服务器和数据库,检查大页使用情况
大页是惰性分配的,用到才会分配。随着数据库的使用,可以在/proc/meminfo中查看HugePages_Free是否已经减少。如果已经减少,表明已经使用到HugePage Memory。
三、 透明大页
在一些Linux系统中,transparent hugepage被默认开启,它允许大页做动态的分配,而不是系统启动后就分配好,根据Oracle MOS DOC:1557478.1,transparent hugepage导致了很多的问题,建议将其关闭。
1. 查看是否启用
-
#未启用应该看到[never]
-
cat /sys/kernel/mm/transparent_hugepage/enabled
如果这个文件不存在,则检查
-
#未启用应该看到[never]
-
cat /sys/kernel/mm/redhat_transparent_hugepage/enabled
如果2个文件都不存在,说明系统内核中移除了THP,例如OEL 7。
2. 关闭透明大页
- Redhat & Centos
-
# 重启后失效
-
echo never > /sys/kernel/mm/transparent_hugepage/enabled
-
echo never > /sys/kernel/mm/transparent_hugepage/defrag
-
-
# 开机时设置never到以上文件中
-
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.d/rc.local
-
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
-
-
chmod +x /etc/rc.d/rc.local
- SUSE Linux(区别在于开机设置never需要配置到的文件不同)
-
# 重启后失效
-
echo never > /sys/kernel/mm/transparent_hugepage/enabled
-
echo never > /sys/kernel/mm/transparent_hugepage/defrag
-
-
# 开机时设置never到以上文件中
-
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/init.d/boot.local
-
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/init.d/boot.local
-
-
chmod +x /etc/init.d/boot.local
参考
Oracle Memory Management and HugePage (连载二)_ITPUB博客
Oracle Memory Management and HugePage (连载三) _ITPUB博客
【云和恩墨】性能优化:Linux环境下合理配置大内存页(HugePage) - ^_^小麦苗^_^ - 博客园
《Linux性能优化实战》笔记(八)—— 内存是怎么工作的_Hehuyi_In的博客-CSDN博客
Linux之关闭大页【即关闭透明大页】_LawsonAbs's Spiritual Home-CSDN博客_关闭大页
HugePages on Oracle Linux 64-bit (文档 ID 361468.1)
Oracle Linux: Shell Script to Calculate Values Recommended Linux HugePages / HugeTLB Configuration (Doc ID 401749.1)
HugePages on Linux: What It Is... and What It Is Not... (Doc ID 361323.1)
What is Memlock and How to Calculate the Values for Memlock? (Doc ID 2511230.1)
[转帖]Linux 页表、大页与透明大页的更多相关文章
- Linux关闭透明大页配置
一.为何要关闭透明大页 A--MOS获取 . #翻译 由于透明超大页面已知会导致意外的节点重新启动并导致RAC出现性能问题,因此Oracle强烈建议禁用透明超大页面. 另外,即使在单实例数据库环境 ...
- 禁用Linux透明大页
Oracle 安装时官方建议关闭Linux的透明大页,防止内存延迟分配导致的性能问题 https://docs.oracle.com/cd/E11882_01/install.112/e47689/p ...
- 【转帖】linux内存管理原理深入理解段式页式
linux内存管理原理深入理解段式页式 https://blog.csdn.net/h674174380/article/details/75453750 其实一直没弄明白 linux 到底是 段页式 ...
- 转:// LINUX下为ORACLE数据库设置大页--hugepage
一.在解释什么情况下需要开启大页和为啥需要开启大页前先了解下Linux下页的相关的知识:以下的内容是基于32位的系统,4K的内存页大小做出的计算1)目录表,用来存放页表的位置,共包含1024个目录en ...
- Transparent HugePages(透明大页)
Transparent HugePages(透明大页) 1. 介绍 从RedHat6, RedHat7, OL6, OL7 SLES11 and UEK2 kernels开始,透明大页默认是被开启的以 ...
- oracle之 关闭透明大页
方法一: 1.设置/etc/grub.conf文件,添加 transparent_hugepage=never ,在系统启动是禁用 [root@hbdw1 ~]# cat /etc/grub.conf ...
- linux的一页是多大
命令 getconf PAGESIZE 结果为4096,即一页=4096字节=4KB(注意是Byte,1B=8bit) 在使用mmap映射函数时,它的实际映射单位也是以页为单位的,即不过我们把MAP_ ...
- [转帖]Linux下逻辑地址、线性地址、物理地址详细总结
Linux下逻辑地址.线性地址.物理地址详细总结 https://www.cnblogs.com/alantu2018/p/9002441.html 总结的挺好的 现在应该是段页式管理 使用MMU和T ...
- Thermostat:双层存储结构的透明巨页内存管理机制
这是一篇由密歇根大学的Neha Agarwal 和 Thomas F. Wenisch,发表在计算机系统顶会ASLOS的论文,Thermostat: Application-transparent P ...
- [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)
Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...
随机推荐
- 机器学习周刊03:如何学习深度学习?2024 年学习生成式 AI 路线图、如何构建高效的RAG系统、苹果 腾讯最新论文、阿里DreaMoving
腾讯推出的 AppAgent,是一个多模态智能体,通过识别当前手机的界面和用户指令直接操作手机界面,能像真实用户一样操作手机! 机器学习周刊:关注Python.机器学习.深度学习.大模型等硬核技术 1 ...
- 使用 Zpan 搭建低成本个人私有网盘,还不限速
摘要:本文就介绍一个不限速的低成本个人网盘--ZPan,相较于老牌的私有网盘 OwnCloud 等,Zpan 有一个独有的优势:不限速. 本文分享自华为云社区<使用 Zpan 搭建低成本个人私有 ...
- 华为云企业级Redis:助力VMALL打造先进特征平台
摘要:当电商平台对AI算法模型的需求越来越多,特征数据平台的统一建设是不少开发团队头疼的事情.因为只有通过统一的特征数据存储,才能改变原有的"数据孤岛",解决生产重复造轮子的窘境. ...
- 华山论“件”:Kafka、RabbitMQ、RocketMQ技能大比拼
摘要:主流的消息中间件包含Kafka.RabbitMQ和RocketMQ,本期云图说为您介绍它们之前的差异. 本文分享自华为云社区<第234期 华山论"件"-Kafka.Ra ...
- ios安全加固 ios 加固方案
目录 一.iOS加固保护原理 1.字符串混淆 2.类名.方法名混淆 3.程序结构混淆加密 4.反调试.反注入等一些主动保护策略 二 代码混淆步骤 1. 选择要混淆保护的ipa文件 2. 选择要混淆 ...
- Solon 开发进阶
Solon 开发进阶 一.插件扩展机制 二.体外扩展机制 三.常用配置说明 四.启动参数说明 五.全局异常订阅 本系列在内核知识的基础上做进一步延申.主要涉及: 插件扩展体系 体外扩展体系 常用配置 ...
- python jira 取提出指向未解决的问题
#!/usr/bin/python # -*- coding: utf-8 -*- import sys, os,time,requests,datetime import schedule from ...
- MIGO BAPI_GOODSMVT_CREATE创建及增强
1.MIGO过账BAPI新增字段 BAPI新增收货行号字段,保存外围系统的数据 1.1.MATDOC表新增收货行号 1.2.MSEG表新增收货行号 创建DDL视图用于扩展NSDM_E_MSEG 1.3 ...
- HTML5 postMessage 跨域跨窗口传递消息
父页面代码: <!DOCTYPE html> <html> <head> <title>选择位置demo</title> <meta ...
- 【C++】使用 curl 库配置 HTTP 的 Post/Get 请求响应数据(封装一个简单类)
2023.7.18 Update: [LibCurl]C++使用libcurl实现HTTP POST和GET 要想使用 LibCURL 库,首先需配置 CURL 库 参考链接:[C++开源库]Wind ...