Ank*_*wal 2 linux process kernel memory virtual-memory
因此,如果 n 个进程共享一个大小为 M 的库 L,那么对它们的 PSS 的贡献是 M/n。
现在想象其中一个进程终止。所以贡献是 M/(n-1)。
问题 1:我的问题是这种变化多久会反映在仍在运行和使用共享库的进程的 PSS 值中?
Q2:作为一个简单的例子,假设只有两个进程在使用大小为 100K 的共享库 L。PSS 对每个进程的贡献是 50K。现在当 P2 死亡时,它是唯一使用 L 的进程。所以它的 PSS 应该增加并变成 100K。这会在多长时间内发生,在 P2 死后,还是在一段时间后?经过多少时间?
更改会立即反映出来。一路上没有缓存。当您阅读时/proc/<pid>/smaps,您实际上触发了对该进程的页表的遍历。有关映射的信息会在此过程中累积,然后显示,没有任何缓存。
/proc/<pid>/smaps文件背后的代码在中fs/proc/task_mmu.c,特别是show_smap函数。
该函数执行walk_page_rangewithsmaps_pte_range作为 PTE 回调。smaps_pte_range本身将信息积累在一个struct mem_size_stats.
该代码负责的部分是PSS:
mapcount = page_mapcount(page);
if (mapcount >= 2) {
if (pte_dirty(ptent) || PageDirty(page))
mss->shared_dirty += ptent_size;
else
mss->shared_clean += ptent_size;
mss->pss += (ptent_size << PSS_SHIFT) / mapcount;
} else {
if (pte_dirty(ptent) || PageDirty(page))
mss->private_dirty += ptent_size;
else
mss->private_clean += ptent_size;
mss->pss += (ptent_size << PSS_SHIFT);
}
Run Code Online (Sandbox Code Playgroud)
(您可以在此处看到,如果页面Shared实际上被多次映射,则只能在该部分中进行计算- 否则将其计算为私有。)
page_mapcount内联定义linux/mm.h并简单地访问 a struct page:
static inline int page_mapcount(struct page *page)
{
return atomic_read(&(page)->_mapcount) + 1;
}
Run Code Online (Sandbox Code Playgroud)
所以 PSS 是“总是最新的”。