博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 大叶内存,hugepages大叶内存
阅读量:6485 次
发布时间:2019-06-23

本文共 4174 字,大约阅读时间需要 13 分钟。

就Linux应用程序而言,使用的都是虚拟地址,当应用程序读写一个指定的虚拟地址时,内存管理单元会自动进行虚拟地址到物理地址的转换。一个虚拟

地址可以映射到多个物理地址,但当前映射到哪一个物理地址取决于当前的页表(Page

Table,一个虚拟地址到物理地址的映射转换表)内容,页表存储在主存储器中,查询速度相对比较慢。为了提高地址转换性能,大多数体系架构都提供一个快

速查找缓冲

要使用HugeTLB特性,当然需要首先打开内核的相关编译选项:

其中:

HugePages_Total:系统当前总共拥有的HugePages数目。

HugePages_Free:系统当前总共拥有的空闲HugePages数目。

HugePages_Rsvd:系统当前总共保留的HugePages数目,更具体点就是指程序已经向系统申请,但是由于程序还没有实质的HugePages读写操作,因此系统尚未实际分配给程序的HugePages数目。

HugePages_Surp:指超过系统设定的常驻HugePages数目的数目。

Hugepagesize:每一页HugePages的大小。

虽然尝试对上面这几个字段解释了一通,但HugePages_Rsvd和HugePages_Surp貌似仍然不够清楚,下面我们以实例数据来看,不过在此之前需要讲解另外几个内核参数:

其中:/proc/sys/vm/nr_hugepages,就是用于设定系统拥有的常驻HugePages数目的/proc接口,可读可写,比如修改常驻HugePages数目为10:

这个值当然并不是echo多少就是多少,它根据系统当前的可用内存来计算,比如如下,2G内存当然不可能会有1000000个HugePages,系统根据当前可用物理内存计算出可以组成的HugePages数目为899:

接口/proc/sys/vm/nr_hugepages_mempolicy和/proc/sys/vm/nr_hugepages的功用类似,

但是它只出现在NUMA系统上,用于更精细的HugePages申请分配。比如,对于一个具有2个NUMA节点的系统,申请100个HugePages页

面(先清0,以便重新生成HugePages页面):

/proc/sys/vm/nr_hugepages接口会按照当前修改nr_hugepages的进程的NUMA策略进行HugePages分

配,当然,默认情况下就是系统当前所有在线NUMA节点平均分配这些HugePages,除非那个NUMA节点本身没有足够的可用连续内存来生成

HugePages,那么此时HugePages将由另外一个NUMA节点生成。

通过/proc/sys/vm/nr_hugepages_mempolicy接口,可以指定HugePages页面具体由哪个NUMA节点生成:

上面先清0,以便系统重新生成HugePages页面,前40个HugePages页面全部在NUMA节点0上生成,而后20个(即

60-40)HugePages页面全部在NUMA节点1上生成,再接下来的20个(即80-60)HugePages页面平均由NUMA节点0和1上生

成,即此时虽然使用的nr_hugepages_mempolicy接口,但由于没有指定NUMA策略,所以默认就是平均分配,最后即便是指定了NUMA

策略,但由于使用的是nr_hugepages接口,所以仍然是平均分配。上面是增加HugePages页面的情况,减少的话也是类似:

第一个是平均减少,各自减少10个,第二个是仅由NUMA节点1减少20个,第三个是仅由NUMA节点0减少25个。当然,系统也提供有直接查看/设置某个NUMA节点上HugePages页面分配的接口:

关于NUMA节点HugePages页面分配以及numactl命令还有更多细节,请参考

编译它为执行程序eg1,eg1使用8M内存,即需要4页HugePages,设定常驻HugePages数为3,可超出常驻HugePages使用数为0,此时执行eg1会提示内存分配失败:

如果设定常驻HugePages数大于等于4,eg1当然可以执行成功,但也可以设定nr_overcommit_hugepages大于等于1同

样也可以让eg1成功执行,即只要nr_hugepages + nr_overcommit_hugepages大于等于4,此处eg1就可成功执行:

回过头来看HugePages_Total、HugePages_Free、HugePages_Rsvd、HugePages_Surp这四个字段:

HugePages_Total大多数情况下等于/proc/sys/vm/nr_hugepages(后面用nr_hugepages表示)的值,但当

/proc/sys/vm/nr_overcommit_hugepages(后面用nr_overcommit_hugepages表示)大于0

时,HugePages_Total会超过nr_hugepages,但肯定小于等于nr_hugepages +

nr_overcommit_hugepages,即:nr_hugepages <= HugePages_Total <=

nr_hugepages + nr_overcommit_hugepages。

HugePages_Free、HugePages_Rsvd、HugePages_Surp来看实例,先做一些设置:

然后,另开一个shell终端执行eg1程序:

就让eg1程序停在这,此时eg1程序已经执行了init_hugepage_seg();,即已经向系统申请4页HugePages,但还没有进

行实质内存读写操作wr_to_array();/rd_from_array();,回到之前的shell终端看HugePage信息:

此时HugePages_Total值为4,为eg1程序申请的HugePages数;HugePages_Free为4,表示系统尚未把这4页

HugePages分配给eg1程序,所以它们都处于free状态,值得注意的是,虽然它们处于free状态,但已经不能再分配作为他用,要测试的话只需

把前面eg1.c文件拷贝为eg2.c,并修改其中shmget函数的key值为2,然后gcc编译为eg2,在当前这个状态下再执行eg2则会提

示:“shmget error!: Cannot allocate

memory”;HugePages_Rsvd也为4,表示程序eg1已经向系统提出申请但尚未获得实际分配的HugePages

数;HugePages_Surp为1,表示超过系统设定的常驻HugePages数目的数目,即是:HugePages_Total(当前是4)

- nr_hugepages(当前是3)。

回到执行eg1程序的shell终端,按一下键盘让eg1程序进行实际读写操作后再回到之前的shell终端看HugePage信息:

此时eg1程序已经进行了实际读写操作,但是尚未释放HugePages内存:

所以看到的HugePages_Total等于4,HugePages_Free等于0,表示4页HugePages都被eg1程序使用

中;HugePages_Rsvd等于0自然是表示eg1程序已经获得了HugePages内存分配。HugePages_Surp为1,表示当前超过系

统设定的常驻HugePages数目的数目还是1。

eg1程序退出后自然数据又都恢复成初始状态了,注意此时HugePages_Surp归为0了,表示那些非常驻HugePages被实时的释放回系统

了,另外,如果在它们还没有释放回系统此前修改了常驻HugePages数目,那么这些HugePages_Surp的HugePages会优先被选择成

为常驻HugePages:

一般情况下,几个不等式为:

nr_hugepages <= HugePages_Total <= nr_hugepages + nr_overcommit_hugepages

HugePages_Free <= HugePages_Total

HugePages_Rsvd <= HugePages_Free

HugePages_Surp = HugePages_Total - nr_hugepages <= nr_overcommit_hugepages

那么特殊情况下,比如当前nr_hugepages为100,使用中的HugePages数目也为100,如果此时修改nr_hugepages为80,

那么即便当前nr_overcommit_hugepages为0,这多出的使用中的20个HugePages也会被计算在HugePages_Surp

中,同时此时也不再能够申请HugePages内存了,直到满足上面几个不等式为止。

被用作HugePages的内存页是不会被系统交换出去(swapped

out)的,并且由于HugePages需要更大的连续物理内存,所以在系统启动时更容易获得更多的HugePages内存,并且还能尽量保证这些

HugePages内存页连续,通过通过添加对应的boot kernel参数来实现这点:

如上面当前内核boot命令行参数设定HugePages内存页10个(hugepages=10),默认HugePages内存页大小为4M,但

Linux X86-64不支持,所以看到的Hugepagesize仍然只是2M(2048

kB)。/proc/sys/vm/nr_hugepages接口改变的是默认HugePages内存页大小的数目,如果系统支持多种大小的

HugePages,改变它们各自的数目需要/sys接口:

我的系统只有一种大小的HugePages,所以只有一个hugepages-2048kB/目录,如果有多种大小的HugePages,那么自然

就会有多个hugepages-${size}kB/这样的目录。每一个目录下存在同样命名的一些文件,其中有三个可读写,通过这几个可读写的接口便可做

相应的修改设置,其它只读:

转载地址:http://yqnuo.baihongyu.com/

你可能感兴趣的文章
用PyRestful快速构建Tornado下REST APIs 的支持
查看>>
【转载】MiniUtilityFramework(七):STRING
查看>>
[mysql] 如何将拷贝过来的数据 *.ibd 文件生效 及查看数据存储位置
查看>>
windows 下,go语言 交叉编译
查看>>
Python装饰器实现异步回调
查看>>
从 C++ 到 Objective-C 的快速指南
查看>>
IO流-ZIP文档
查看>>
【Android】14.1 内部文件存储和读取
查看>>
BZOJ 1026 windy数
查看>>
Chapter 3. 数据库约束(设计器操作)
查看>>
【Python】从0开始写爬虫——豆瓣电影
查看>>
Android Vibrator震动效果
查看>>
GO语言总结(2)——基本类型
查看>>
动态加载js文件
查看>>
jsp自定义分页标签
查看>>
ntp时间同步服务器
查看>>
HotSpot Builder Utility安装指南
查看>>
Android Tab类型主界面 Fragment+TabPageIndicator+ViewPager
查看>>
yii的layouts的使用
查看>>
linux安装php 按 apache方式
查看>>