
Wenn also n Prozesse eine Bibliothek L mit der Größe M gemeinsam nutzen, beträgt der Beitrag zu ihrem PSS M/n.
Stellen Sie sich nun vor, einer der Prozesse würde beendet. Der Beitrag wäre dann M/(n-1).
F1: Meine Frage lautet: Wie schnell wird diese Änderung in den PSS-Werten von Prozessen berücksichtigt, die noch ausgeführt werden und die gemeinsam genutzte Bibliothek verwenden?
F2: Nehmen wir als trivialen Fall an, dass nur zwei Prozesse eine gemeinsam genutzte Bibliothek L mit einer Größe von 100 KB verwenden. Der PSS-Beitrag zu jedem Prozess beträgt 50 KB. Wenn P2 nun stirbt, ist er der einzige Prozess, der L verwendet. Daher sollte sein PSS ansteigen und 100 KB betragen. Wie schnell wird dies geschehen, sobald P2 stirbt oder nach einiger Zeit? Nach wie viel Zeit?
Antwort1
Die Änderung wird sofort angezeigt. Es erfolgt kein Zwischenspeichern. Wenn Sie lesen /proc/<pid>/smaps
, lösen Sie tatsächlich eine Durchquerung der Seitentabelle dieses Prozesses aus. Informationen zu den Zuordnungen werden dabei gesammelt und dann ohne Zwischenspeichern angezeigt.
Der Code hinter der /proc/<pid>/smaps
Datei befindet sich in fs/proc/task_mmu.c
, und zwar dieshow_smap
Funktion.
Diese Funktion führt ein walk_page_range
mitsmaps_pte_range
als PTE-Rückruf. smaps_pte_range
selbst sammelt die Informationen in einem struct mem_size_stats
.
Der Teil des Codes, der dafür verantwortlich PSS
ist:
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);
}
(Sie können hier sehen, dass Seiten in dem Teil nur dann berücksichtigt werden können, Shared
wenn sie tatsächlich mehr als einmal zugeordnet sind – andernfalls werden sie als privat berücksichtigt.)
page_mapcount
ist inline in definiert linux/mm.h
und greift einfach auf ein zu struct page
:
static inline int page_mapcount(struct page *page)
{
return atomic_read(&(page)->_mapcount) + 1;
}
Damit ist PSS „immer auf dem neuesten Stand“.