
Portanto, se n processos estão compartilhando uma biblioteca L com tamanho M, então a contribuição para seu PSS é M/n.
Agora imagine que um dos processos termine. Portanto a contribuição seria M/(n-1).
Q1: Minha pergunta é quando essa mudança será refletida nos valores PSS dos processos que ainda estão em execução e usando a biblioteca compartilhada?
Q2: Como um caso trivial, suponha que apenas dois processos estejam usando uma biblioteca compartilhada L de tamanho 100K. A contribuição do PSS para cada processo é de 50K. Agora, quando P2 morre, é o único processo que usa L. Portanto, seu PSS deve aumentar e se tornar 100K. Quando isso acontecerá, assim que P2 morrer, ou depois de algum tempo? Depois de quanto tempo?
Responder1
A mudança é refletida imediatamente. Não há cache ao longo do caminho. Ao ler /proc/<pid>/smaps
, você realmente aciona uma travessia da tabela de páginas desse processo. As informações sobre os mapeamentos são acumuladas ao longo do caminho e depois exibidas, sem qualquer armazenamento em cache.
O código por trás do /proc/<pid>/smaps
arquivo está em fs/proc/task_mmu.c
, especificamente oshow_smap
função.
Essa função faz um walk_page_range
withsmaps_pte_range
como o retorno de chamada do PTE. smaps_pte_range
ele mesmo acumula as informações em um arquivo struct mem_size_stats
.
A parte desse código responsável por PSS
faz:
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);
}
(Você pode ver aqui que as páginas só podem ser contabilizadas na Shared
parte se forem realmente mapeadas mais de uma vez - caso contrário, serão contabilizadas como privadas.)
page_mapcount
é definido inline in linux/mm.h
e simplesmente acessa a struct page
:
static inline int page_mapcount(struct page *page)
{
return atomic_read(&(page)->_mapcount) + 1;
}
Portanto o PSS está “sempre atualizado”.