
Entonces, si n procesos comparten una biblioteca L con tamaño M, entonces la contribución a su PSS es M/n.
Ahora imagina que uno de los procesos termina. Entonces la contribución sería M/(n-1).
P1: Mi pregunta es ¿qué tan pronto se refleja este cambio en los valores de PSS de los procesos que aún se ejecutan y utilizan la biblioteca compartida?
P2: Como caso trivial, supongamos que solo dos procesos utilizan una biblioteca compartida L de tamaño 100K. La contribución del PSS a cada proceso es de 50K. Ahora, cuando P2 muere, es el único proceso que usa L. Por lo tanto, su PSS debería aumentar y convertirse en 100K. ¿Qué tan pronto sucederá esto, tan pronto como muera P2, o después de algún tiempo? ¿Después de cuánto tiempo?
Respuesta1
El cambio se refleja inmediatamente. No hay almacenamiento en caché en el camino. Cuando lees /proc/<pid>/smaps
, en realidad activas un recorrido por la tabla de páginas de ese proceso. La información sobre las asignaciones se acumula a lo largo del camino y luego se muestra, sin ningún almacenamiento en caché.
El código detrás del /proc/<pid>/smaps
archivo está en fs/proc/task_mmu.c
, específicamente elshow_smap
función.
Esa función hace una walk_page_range
consmaps_pte_range
como devolución de llamada de PTE. smaps_pte_range
él mismo acumula la información en un archivo struct mem_size_stats
.
La parte de ese código responsable de PSS
hace:
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);
}
(Puede ver aquí que las páginas solo se pueden contabilizar en la Shared
parte si en realidad se asignan más de una vez; de lo contrario, se contabilizan como privadas).
page_mapcount
se define en línea linux/mm.h
y simplemente accede a struct page
:
static inline int page_mapcount(struct page *page)
{
return atomic_read(&(page)->_mapcount) + 1;
}
Entonces PSS está "siempre actualizado".