合 Linux 标准大页和透明大页
Linux 标准大页和透明大页简介
HugePages是Linux内核的一个特性,它允许更大的页面管理内存,以替代4KB的页面大小。
操作系统把逻辑地址映射成物理地址时,需要把映射关系也存储到一块内存中,这部分内容就是页表(PageTables)。操作系统虚拟内存到物理内存的映射表,就被称为页表。计算机内存是通过表映射(页表)的方式进行内存寻址。CPU 拥有内置的内存管理单元,包含这些页面的列表,每个页面通过页表条目引用。当内存越来越大的时候, CPU 需要管理这些内存页的成本也就越高,这样会对操作系统的性能产生影响。
在64位机器上,目前系统默认内存以4KB为一个页,作为内存寻址的最小单元,随着内存和进程数的不断增大,页表的大小将会不断增大。内存是以块即页的方式进行管理的,当前大部分系统默认的页大小为 4096 bytes 即 4K 。 1MB 内存等于 256 页; 1GB 内存等于 256000 页。
1 2 | [lhrxxt@xmmup ~]$ getconf PAGESIZE 4096 |
在Linux操作系统中,即使是同一块共享内存,每个进程中的逻辑地址也是不相同的,因此不同进程中的映射表项也不相同。在64位的机器上,每个4k页需要占用大约8字节的内存,一台48GB内存的机器,如果分配了24GB的共享内存,则每个进程的页表大小为24GB/4K*8=48MB
;如果连接上500个进程,那么页表的大小将是500*48MB=24GB
。这会立刻把机器上的所有内存吃光【可以得到,大约1G的共享内存,若有一个进程连接,则页表大小大约为2MB】。当然,并不是每个新连接一连接上来就会分配48MB,而是当进程需要建立逻辑地址和物理地址之间的映射关系时才会分配,所以,进程占用的页表空间是缓慢增加的,但最终还是会占用很大的页表内存。
页表是必须装在内存的,而且是在CPU内存,太大就会发生大量miss,内存寻址性能就会下降。
要查看是否存在大页表的问题,可以使用如下的命令来检查页表的大小:
1 2 | [root@lhrdb ~]# cat /proc/meminfo | grep PageTables PageTables: 1932200 kB |
如果发现页表的大小不是几十兆,而是达到了1GB以上,就说明数据库存在此问题。有的数据库系统可以达到50GB的页表,严重浪费内存。基于共享内存的多进程架构的程序都会存在此问题。
Huge Page就是为了解决这个问题,它使用2MB的大页代替传统小页4KB来管理内存,这样页表大小就可以控制的很小,进而全部装在CPU内存,防止出现miss。在 Linux 中,大页分为两种:一是静态大页面(Static Huge Pages,SHP)也称为标准大页,二是透明大页面(Transparent Huge Pages,THP)。从它们的名字就可以看出,SHP是静态的,而THP是动态的。由于THP是在运行期做分配和管理,因此会有一定程度的延迟,对于内存密集型的应用(例如数据库类)十分不利,必须关闭它。
标准大页(Huge Pages)
Huge pages 是从 Linux Kernel 2.6 后被引入的,目的是通过使用大页内存来取代传统的 4kb 内存页面, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。
Huge pages 有两种格式大小: 2MB 和 1GB , 2MB 页块大小适合用于 GB 大小的内存, 1GB 页块大小适合用于 TB 级别的内存; 2MB 是默认的页大小。
标准大页的页面大小:
1 2 | [root@docker35 ~]# grep Hugepagesize /proc/meminfo Hugepagesize: 2048 kB |
使用Huge pages优点
- 适合大内存或内存密集型应用(例如数据库)的调优。
- 减小页表尺寸(避免页表过大),降低查找缓存(TLB,Translation Lookaside Buffer)的cache-miss,加速VM内存转换。
- 可以使花费在内存管理上的 CPU 时间更少,从而提高性能。
使用Huge pages缺点
当然使用 Huge pages 也会存在某些缺点:
支持Markdown