
したがって、n 個のプロセスがサイズ M のライブラリ L を共有している場合、PSS への寄与は M/n になります。
ここで、プロセスの 1 つが終了したと想像してください。この場合、寄与は M/(n-1) になります。
Q1: 質問は、この変更が、まだ実行中で共有ライブラリを使用しているプロセスの PSS 値にどれくらい早く反映されるかということです。
Q2: 単純なケースとして、サイズが 100K の共有ライブラリ L を使用しているプロセスが 2 つだけであるとします。各プロセスへの PSS の寄与は 50K です。ここで P2 が終了すると、L を使用している唯一のプロセスになります。したがって、その PSS は増加して 100K になるはずです。これはいつ発生しますか。P2 が終了してすぐに発生しますか。それとも、しばらくしてから発生しますか。どのくらいの時間がかかりますか。
答え1
変更はすぐに反映されます。途中でキャッシュは行われません。 を読み取ると/proc/<pid>/smaps
、実際にはそのプロセスのページ テーブルのトラバースがトリガーされます。マッピングに関する情報は途中で蓄積され、キャッシュされずに表示されます。
ファイルの背後にあるコード/proc/<pid>/smaps
はfs/proc/task_mmu.c
、具体的にはshow_smap
関数。
その関数walk_page_range
はsmaps_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);
}
Shared
(ここで、ページは実際に複数回マップされている場合にのみパーツに計上されることがわかります。それ以外の場合はプライベートとして計上されます。)
page_mapcount
は でインライン定義されておりlinux/mm.h
、単に にアクセスしますstruct page
。
static inline int page_mapcount(struct page *page)
{
return atomic_read(&(page)->_mapcount) + 1;
}
つまり、PSS は「常に最新」です。