我在谷歌上搜索了很多关于“每个过程的页面共享因子”负责的内容,但一无所获。这对我来说很有趣,我目前没有任何问题,只是好奇(想知道更多)。在 sysctl 中是:
vm.pmap.shpgperproc
提前致谢
我在谷歌上搜索了很多关于“每个过程的页面共享因子”负责的内容,但一无所获。这对我来说很有趣,我目前没有任何问题,只是好奇(想知道更多)。在 sysctl 中是:
vm.pmap.shpgperproc
提前致谢
首先要注意的是它shpgperproc
是一个加载器可调参数,所以它只能在引导时使用适当的指令 in 设置loader.conf
,之后它是只读的。
第二点要注意的是它是在 中定义的<arch>/<arch>/pmap.c
,它处理 vm 子系统的体系结构相关部分。特别是,它实际上并没有出现在 amd64 中pmap.c
——它最近被删除了,我将在下面讨论一下。但是,它存在于其他架构(i386、arm、...)中,并且在每个架构上都以相同的方式使用;即,它显示如下:
void
pmap_init(void)
{
...
TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
它没有在其他任何地方使用。pmap_init()
仅调用一次:在引导时作为 vm 子系统初始化的一部分。maxproc
, 只是可以存在的最大进程数(即kern.maxproc
),并且cnt.v_page_count
只是可用内存的物理页数(即vm.stats.v_page_count
)。
Apv_entry
基本上只是一个物理页面的虚拟映射(或者更准确地说是 a struct vm_page
,所以如果两个进程共享一个页面并且都映射了它们,那么pv_entry
每个映射都会有一个单独的结构。因此给定一个页面 ( struct vm_page
) 需要脏或分页或需要更新hw页表的东西,通过查看对应的pv_entry
s列表可以很容易地找到对应的映射虚拟页面列表(例如,看一下i386/i386/pmap.c:pmap_remove_all()
)。
s的使用pv_entry
使某些 VM 操作更高效,但当前的实现(至少对于 i386)似乎为 s 分配了静态量的空间(参见pv_maxchunks
,它是基于 设置的pv_entry_max
)pv_chunk
,用于管理pv_entry
s。如果内核在取消分配非活动的之后无法分配 a pv_entry
,它就会恐慌。
因此,我们要pv_entry_max
根据pv_entry
我们想要的空间来设置;显然,我们至少需要与 RAM 页面一样多(这是cnt.v_page_count
从哪里来的)。然后我们要考虑到许多页面将被不同进程多重虚拟映射的事实,因为pv_entry
需要为每个这样的映射分配a。因此shpgperproc
- 所有拱门的默认值为 200 - 只是一种缩放它的方法。在一个将在进程之间共享许多页面的系统上(例如在运行 apache 的负载很重的 Web 服务器上),显然可能会用完pv_entry
s,因此需要增加它。
我现在附近没有 FreeBSD 机器,但似乎这个参数是在 pmap.c 中定义和使用的,http: //fxr.watson.org/fxr/ident?v=FREEBSD7&im=bigexcerpts&i=shpgperproc