Windows/윈도우 공통

프로세스 워킹셋 (working set)

99iberty 2013. 10. 25. 13:34

 

http://yunsoul.egloos.com/4973792

 

윈도우가상 메모리 방식으로 프로세스 메모리를 관리한다. 그런데 가상 메모리라는 것이 페이지 파일(Pagefile, pagefile.sys)을 이용하는 것이기 때문에(물론 물리 메모리도 이용한다) 순수하게 물리 메모리(RAM) 만을 이용하는 것 보다 속도가 느릴 수 밖에 없다. 물리 메모리에 상주해 있는 데이터는 단순히 해당 주소를 참조해서 Read/Write 하면 되지만, 페이지 파일에 존재하는 데이터를 Read/Write 하려면 페이지 폴트(Page Fault), 페이지 스왑(Page Swap)과정 등을 거쳐야만 하기 때문이다.

따라서 윈도우는 이를 좀더 보완하기 위해서 프로세스 워킹 셋(Process Working Set)이라는 것을 두어서 프로세스의 메모리 처리 속도를 향상 시켜 준다. 즉, 프로세스가 자주 참조하는 데이터를 물리 메모리 영역에 상주 시켜서 페이지 폴트나 페이지 스왑 과정 없이 해당 데이터를 참조할 수 있게 해준다.

각 프로세스는 자신만의 프로세스 워킹 셋을 가지며, 프로세스 워킹 셋에는 해당 프로세스가 자주 참조하는 코드 페이지(code pages)와 데이터 페이지(data pages)가 포함된다.

만약, 프로세스가 프로세스 워킹 셋에 존재하지 않는 페이지를 참조하게 되면 페이지 폴트가 발생한다. 그리고 VMM(Virtual Memory Manager)은 해당 페이지를 프로세스 워킹 셋에 추가 한다.

물리 메모리가 부족한 상황에서는 VMM이 물리 메모리 확보를 위해서 프로세스 워킹 셋에서 오랫동안 참조 되지 않은 페이지와 자주 참조 되지 않은 페이지를 제거한다. 이러한 과정을 Trim이라고 하며, Trim 작업이 많이 수행될 수록 페이지 폴트가 발생하는 빈도는 증가하게 된다.

페이지 폴트의 발생 빈도가 증가하면 그만큼 메모리 처리 속도가 증가할 수 있다고 볼 수 있겠지만, 어차피 자주 참조되지 않는 페이지들을 프로세스 워킹 셋에서 제거하는 것이기 때문에 그 영향은 미비하다고 볼 수 있으며, 오히려 효율적인 메모리 활용과 가용 메모리 공간 확보 측면의 장점을 가진다고 불 수 있다.

그렇다면 작업 관리자(taskmgr.exe)와 Process Explorer를 이용해서 프로세스 워킹 셋을 확인해 보자.




작업 관리자의 "메모리 사용" 항목이 바로 각 프로세서에 대한 프로세스 워킹 셋의 크기를 보여주는 것이다.
그리고 Process Explorer의 경우에는 "Working Set" 항목이 이에 해당한다.

그리고, 작업 관리자의 "VM 크기" 항목이 Process Explorer의 "Private Bytes" 항목임을 알 수 있다.





위 그림을 보면 csrss.exe 프로세스의 프로세스 워킹 셋의 크기가 17,756K이며, 이 안에는 공유 메모리 또한 포함됨을 알 수 있다.
일반적으로 프로세스 워킹 셋에는 code와 data 그리고 공유 메모리가 포함되며, Private Bytes(VM 크기 항목)에는 data만 포함된다.


[ 프로세스 워킹 셋 처리 API ]

(1) 프로세스 워킹 셋의 크기를 구한다.

void GetProcessWorkingSetSize(
HANDLE hProcess,
PSIZE_T lpMinimumWorkingSetSize,
PSIZE_T lpMaximumWorkingSetSize
);

void GetProcessWorkingSetSizeEx(
HANDLE hProcess,
PSIZE_T lpMinimumWorkingSetSize,
PSIZE_T lpMaximumWorkingSetSize,
PDWORD Flags
);

(2) 프로세스 워킹 셋의 크기를 설정한다.

BOOL SetProcessWorkingSetSize(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize
);

void SetProcessWorkingSetSizeEx(
HANDLE hProcess,
SIZE_T dwMinimumWorkingSetSize,
SIZE_T dwMaximumWorkingSetSize,
DWORD Flags
);