我很难理解 Solaris 10 x86 交换分配在存在mlock
ed 共享内存的情况下如何工作。
我写了一个小程序:
- 获取 1G SHM 段 (
shmget
) - 将其附加到进程 (
shmat
) - 锁定其中的一部分(
mlock
第一轮不锁定任何内容,然后是 512M,然后是整个) - 写入 SHM 区域的最后一页,然后是第一页
- 逐步写入整个段
- 释放锁(如果有)
- 拆卸并清理。
swap -s
它在每个操作后打印出以 MB 为单位的值。
输出如下:
- 第 1 轮,否
mlock
:(右侧的值相对于第一个读数)
pid: 2221 mlock size: 0
header: alloc resvd used free [+/- alloc resvd used free]
init: 325 130 456 2873 [+/- 0 0 0 0]
shmget: 326 1154 1480 1849 [+/- 1 1024 1024 -1024]
shmat: 326 1154 1480 1849 [+/- 1 1024 1024 -1024]
touchE: 326 1154 1480 1849 [+/- 1 1024 1024 -1024]
touchS: 326 1154 1480 1849 [+/- 1 1024 1024 -1024]
set1: 582 898 1480 1848 [+/- 257 768 1024 -1025]
set2: 838 642 1480 1848 [+/- 513 512 1024 -1025]
set3: 1093 386 1480 1847 [+/- 768 256 1024 -1026]
set4: 1350 130 1480 1847 [+/- 1025 0 1024 -1026]
set: 1350 130 1480 1847 [+/- 1025 0 1024 -1026]
shmdt: 1350 130 1480 1847 [+/- 1025 0 1024 -1026]
shmctl: 326 130 456 2871 [+/- 1 0 0 -2]
在这里,一切都好。free
列最多比启动时小约 1G。
- 第2轮,
mlock
共享段的前512M:
pid: 2221 mlock size: 536870912
header: alloc resvd used free [+/- alloc resvd used free]
init: 326 130 456 2871 [+/- 0 0 0 0]
shmget: 326 1154 1480 1847 [+/- 0 1024 1024 -1024]
shmat: 326 1154 1480 1847 [+/- 0 1024 1024 -1024]
mlock: 838 642 1480 1334 [+/- 512 512 1024 -1537] <<<<
touchE: 838 642 1480 1334 [+/- 512 512 1024 -1537]
touchS: 838 642 1480 1334 [+/- 512 512 1024 -1537]
set1: 838 642 1480 1334 [+/- 512 512 1024 -1537]
set2: 838 642 1480 1334 [+/- 512 512 1024 -1537]
set3: 1094 386 1480 1334 [+/- 768 256 1024 -1537]
set4: 1350 130 1480 1334 [+/- 1024 0 1024 -1537]
set: 1350 130 1480 1334 [+/- 1024 0 1024 -1537] <<<<
munlock: 1350 130 1480 1846 [+/- 1024 0 1024 -1025]
shmdt: 1350 130 1480 1847 [+/- 1024 0 1024 -1024]
shmctl: 326 130 456 2871 [+/- 0 0 0 0]
- 第三轮,
mlock
全段:
pid: 2221 mlock size: 1073741824
header: alloc resvd used free [+/- alloc resvd used free]
init: 326 130 456 2871 [+/- 0 0 0 0]
shmget: 326 1154 1480 1847 [+/- 0 1024 1024 -1024]
shmat: 326 1154 1480 1847 [+/- 0 1024 1024 -1024]
mlock: 1350 130 1480 822 [+/- 1024 0 1024 -2049] <<<<
touchE: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
touchS: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
set1: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
set2: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
set3: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
set4: 1350 130 1480 822 [+/- 1024 0 1024 -2049]
set: 1350 130 1480 822 [+/- 1024 0 1024 -2049] <<<<
munlock: 1350 130 1480 1846 [+/- 1024 0 1024 -1025]
shmdt: 1350 130 1480 1847 [+/- 1024 0 1024 -1024]
shmctl: 326 130 456 2871 [+/- 0 0 0 0]
在最后两轮中,在 后但在实际触及任何页面之前,该free
列会额外下降 512M 或 1G 。mlock
这种“双重会计”在munlock
通话后就消失了。
谁能解释这种行为?页面是否mlocked
同时保留在实际 RAM 和后备存储中或类似的地方?
SunOS myhost 5.10 Generic_142910-17 i86pc i386 i86pc
答案1
如果你使用迪斯曼,确保交换空间有足够的空间。
当你shmat
一个 SHM 段SHM_SHARE_MMU
(这不是默认的),你会得到一个主义段,自动锁定在内存中(不可分页)。在虚拟内存中,该映射的成本就是分配的 SHM 区域的大小。 (由于无法调出,因此无需保留交换)。mlock
对这些页面没有影响,它们已经被锁定。
如果您附加该段SHM_PAGEABLE
,您会得到迪斯曼部分。那个是可分页的。这最初的成本是一样的。但是,如果您使用mlock
任何内存,mlock
ed 区域将再次考虑其锁定的 RAM 使用情况。所以虚拟内存成本是(whole mapping + mlocked zone)
。
就好像使用 时,SHM_PAGEABLE
映射是在“交换中”创建的,并且您锁定的区域需要“在内存中”进行额外的预留(这些锁定页面的后备存储不会被释放或取消预留)。
所以我所看到的是正常的,符合设计的。
有关这方面的一些信息可以在使用 DISM 对 Oracle Solaris 上的 Oracle 数据库进行动态 SGA 调整(280k PDF)。摘抄:
由于DISM内存不会自动锁定,必须为整个段分配交换空间。 [...]。但如果系统管理员没有意识到需要为 DISM 提供交换空间,这可能会成为一个问题。
(我是那些不知情的系统管理员之一......)
提示:用于pmap -xa
查看您拥有的细分类型。
- 主义:
Address Kbytes RSS Anon Locked Mode Mapped File
...
80000000 1048576 1048576 1048576 1048576 rwxsR [ ism shmid=0x16 ]
^ ^^^
请注意R
模式位中的:此映射没有保留。
- 迪斯曼:
Address Kbytes RSS Anon Locked Mode Mapped File
...
80000000 1048576 1048576 1048576 1048576 rwxs- [ dism shmid=0xa ]
^ ^^^^