따라서 n개의 프로세스가 크기 M의 라이브러리 L을 공유하는 경우 해당 PSS에 대한 기여도는 M/n입니다.
이제 프로세스 중 하나가 종료된다고 상상해 보세요. 따라서 기여도는 M/(n-1)이 됩니다.
질문 1: 내 질문은 이 변경 사항이 아직 실행 중이며 공유 라이브러리를 사용하는 프로세스의 PSS 값에 얼마나 빨리 반영됩니까?입니다.
Q2: 간단한 예로, 두 프로세스만 크기 100K의 공유 라이브러리 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는 "항상 최신 상태"입니다.