
따라서 n개의 프로세스가 M 크기의 라이브러리 L을 공유하는 경우 해당 PSS에 대한 기여도는 M/n입니다.
이제 프로세스 중 하나가 종료된다고 상상해 보세요. 따라서 기여도는 M/(n-1)이 됩니다.
Q1: 내 질문은 이 변경 사항이 아직 실행 중이고 공유 라이브러리를 사용하는 프로세스의 PSS 값에 얼마나 빨리 반영되는지입니다.
Q2: 사소한 사례로 두 프로세스만 크기 100K의 공유 lib L을 사용한다고 가정합니다. 각 프로세스에 대한 PSS 기여도는 50K입니다. 이제 P2가 죽으면 L을 사용하는 유일한 프로세스입니다. 따라서 PSS는 증가하여 100K가 되어야 합니다. P2가 죽자마자, 아니면 얼마 후에 이런 일이 일어날까요? 얼마나 시간이 지나면?
답변1
변경사항은 즉시 반영됩니다. 도중에 캐싱이 없습니다. 을 읽으면 /proc/<pid>/smaps
실제로 해당 프로세스의 페이지 테이블 순회가 트리거됩니다. 매핑에 대한 정보는 도중에 누적된 다음 캐싱 없이 표시됩니다.
파일 뒤의 코드 /proc/<pid>/smaps
는 fs/proc/task_mmu.c
, 특히show_smap
기능.
해당 함수는 walk_page_range
다음 을 수행합니다.smaps_pte_range
PTE 콜백으로. 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는 "항상 최신 상태"입니다.