web-dev-qa-db-ja.com

/ proc / pid / smaps内の特定のプロセスのPSS値が更新される頻度

したがって、n個のプロセスがサイズMのライブラリLを共有している場合、それらのPSSへの寄与はM/nです。

ここで、プロセスの1つが終了するとします。したがって、寄与はM /(n-1)になります。

Q1:私の質問は、この変更が、共有ライブラリを実行および使用しているプロセスのPSS値にどのくらいの期間反映されるかということです。

Q2:些細なケースとして、2つのプロセスだけがサイズ100Kの共有ライブラリLを使用していると仮定します。各プロセスへのPSSの貢献は50Kです。これで、P2が停止すると、Lを使用する唯一のプロセスになります。したがって、そのPSSは増加し、100Kになるはずです。 P2が死ぬとすぐに、またはしばらくして、これはどのくらい早く起こりますか?どのくらいの時間の後?

2
Ankur Agarwal

変更はすぐに反映されます。途中でキャッシュはありません。 /proc/<pid>/smapsを読み取ると、実際にはそのプロセスのページテーブルのトラバーサルがトリガーされます。マッピングに関する情報は途中で蓄積され、キャッシュなしで表示されます。

/proc/<pid>/smapsファイルの背後にあるコードはfs/proc/task_mmu.cにあり、具体的には show_smap 関数です。
その関数は、PTEコールバックとして walk_page_range を使用してsmaps_pte_rangeを実行します。 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_mapcountlinux/mm.hでインラインで定義され、単にstruct pageにアクセスします。

static inline int page_mapcount(struct page *page)
{
    return atomic_read(&(page)->_mapcount) + 1;
}

したがって、PSSは「常に最新」です。

5
Mat