/proc/pid/smaps 内の特定のプロセスの PSS 値はどのくらいの頻度で更新されますか

/proc/pid/smaps 内の特定のプロセスの PSS 値はどのくらいの頻度で更新されますか

したがって、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>/smapsfs/proc/task_mmu.c、具体的にはshow_smap関数。
その関数walk_page_rangesmaps_pte_rangePTE コールバックとして。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 は「常に最新」です。

関連情報