이전 글 「Windows 메모리의 심층(제1회) ── 가상 주소가 물리 RAM이 되는 순간」에서는, Commit된 페이지에 처음 닿는 순간 페이지 폴트 핸들러가 물리 페이지를 할당하는 데까지 따라갔습니다. 그렇다면 그 물리 페이지가 Working Set에서 빠진 뒤에는 어디로 갈까요?
「페이지 파일로 쫓겨난다」로 줄여 설명하는 글을 자주 보지만, 실제로는 그 앞뒤에 여러 상태가 있습니다. 변경되지 않은 페이지는 내용을 남긴 채 Standby로 옮길 수 있습니다. 변경된 페이지는 먼저 Modified에서 다시 쓰기를 기다립니다. 재사용 때는 Free나 Zeroed를 거치기도 하고, 같은 내용이 다시 필요하면 Standby에서 소프트 폴트로 돌아올 수도 있습니다.
이 글은 PFN 데이터베이스를 축으로 한 장의 물리 페이지가 Active, Modified, Standby, Free, Zeroed를 어떻게 이동하는지를 따라갑니다. 숫자 읽기 자체는 도입편 「Windows의 「메모리 사용량」은 무엇을 나타내는가 ── Working Set·Private Bytes·Commit·페이지 파일을 올바르게 읽는 법」을 전제로 합니다.
「Windows 메모리의 심층」 전 3회
- 제1회: 가상 주소와 페이지 폴트
Commit된 가상 페이지가 언제 물리 RAM을 얻는지 따라갑니다. - 제2회(이 글): 물리 페이지의 일생
Working Set에서 벗어난 페이지의 상태 전이와 페이지 파일의 역할을 따라갑니다. - 제3회: 섹션 객체와 복사 온 라이트
DLL, 파일 매핑, 공유 메모리가 물리 페이지를 공유하는 메커니즘을 따라갑니다.
제2회가 답하는 질문은 하나뿐입니다.
Working Set에서 벗어난 물리 페이지는 사라질까요, 디스크로 갈까요, 아니면 RAM에 남을까요?
대상 독자는 Available이 높은데 Standby도 높은 이유, Working Set 트리밍 이후의 동작, 페이지 파일 설정, 메모리 압축을 메커니즘부터 이해하고 싶은 개발자와 운영 담당자입니다. 전제 환경은 Windows 10/11 또는 최신 Windows Server이고, 필요한 배경은 Working Set, Commit, 소프트/하드 폴트의 기초입니다. 난이도는 중급입니다. PFN과 페이지 리스트 같은 내부 용어는 쓰지만, 커널 디버거 없이 RAMMap과 PerfMon으로 관찰할 수 있는 범위에 초점을 둡니다.
1. 먼저 결론
처음에는 오해하기 쉬운 점을 정리합니다.
- Working Set에서 벗어난 페이지가 바로 사라지지는 않습니다.
clean 페이지는 Standby에 남아, 같은 내용이 필요하면 디스크를 읽지 않고 돌아올 수 있습니다. - 변경된 페이지는 바로 재사용할 수 없습니다.
프라이빗 내용은 페이지 파일에, 매핑된 파일은 대응 파일에 다시 쓸 수 있게 된 뒤에야 재사용됩니다. - Available에는 Standby가 포함됩니다.
Standby는 내용을 아직 들고 있는 캐시인 동시에, 필요하면 즉시 가져갈 수 있는 재사용 후보입니다.1 - 페이지 파일에 쓰는 작업은 RAM이 완전히 바닥난 뒤에야 시작하는 일괄 작업이 아닙니다.
Modified 목록과 메모리 압력에 따라 백그라운드에서 진행됩니다.23 - 페이지 파일은 「느린 RAM」만이 아닙니다.
Commit Limit을 넓히고, 변경된 프라이빗 페이지의 백킹 스토어가 되며, 크래시 덤프를 뒷받침합니다.4 - 페이지 파일을 꺼도 메모리 누수는 고쳐지지 않습니다.
Commit Limit이 내려가고, RAM을 효과적으로 쓰는 선택지와 덤프 수집 능력도 잃을 수 있습니다.
한 문장으로 말하면, Windows는 페이지를 버리기 전에 다시 필요할 가능성과, 원래 내용을 복원할 수 있는 장소가 있는지를 확인합니다.
2. PFN 데이터베이스 ── 물리 RAM 쪽의 대장
제1회에서 본 PTE는 가상 페이지에서 물리 페이지로의 변환을 나타냈습니다. 이를 물리 페이지 쪽에서 보고 「이 RAM 페이지는 지금 무엇에 쓰이는가」를 따라가는 대장이 PFN 데이터베이스입니다. PFN은 Page Frame Number의 약자로, 물리 RAM을 페이지 단위로 번호 매긴 것입니다.
PFN 항목은 개념적으로 다음 정보를 추적합니다.
- 물리 페이지의 현재 상태
- 참조 수와 공유 수
- 대응하는 PTE
- 변경되었는지 여부
- 어느 페이지 리스트에 속하는지
- NUMA 노드와 우선순위에 관한 정보
WinDbg에서는 !pfn이 특정 PFN의 정보를, !memusage가 물리 메모리 사용량과 각 페이지 리스트 합계를 표시합니다.56 커널 디버거 없이 같은 세계를 보고 싶다면 Sysinternals RAMMap을 쓸 수 있습니다. Use Counts는 용도와 페이지 리스트를, Priority Summary는 우선순위별 Standby를, Physical Pages는 페이지 단위 사용을 보여 줍니다.7
3. 다섯 상태를 한 그림으로 잇기
이 글은 물리 페이지의 흐름을 다음 다섯 상태로 단순화해 다룹니다. 엄밀히 말하면 현재 Windows에는 우선순위별 Standby, Transition, Bad처럼 여기에 그리지 않은 상태와 리스트가 있고, Active도 단일 「Active 리스트」라기보다 유효 PTE를 통해 Working Set 등에서 참조 중인 상태를 가리킵니다. 그래도 앱의 메모리 동작을 읽는 데는 이 그림이 충분히 쓸모 있습니다.
그림 1: Working Set에서 참조 중인 페이지는 clean이면 Standby로, dirty이면 Modified로 이동합니다. 같은 내용은 돌아올 수 있고, 다른 용도로는 페이지를 직접 재사용하거나 0이 필요한 할당을 위해 Free/Zeroed를 거칩니다.
그림 1의 Mermaid 소스
```text flowchart LR zeroed["Zeroed\n0으로 채움"] -->|첫 Touch| active["Active / Valid\nWorking Set에서 참조 중"] active -->|clean을 트림| standby["Standby\n내용을 유지한 재사용 후보"] active -->|dirty를 트림| modified["Modified\n다시 쓰기 대기"] modified -->|다시 쓰기 완료| standby standby -->|소프트 폴트로 복귀| active standby -->|이전 식별을 버림| free["Free\n아직 0 아님"] standby -->|다른 용도로 직접 재사용| active free -->|0이 필요한 할당용| zeroed ```이 그림에서 가장 중요한 점은 Working Set에서 벗어나는 것과 내용이 사라지는 것은 같지 않다는 것입니다. 또한 Standby 페이지를 다른 용도로 가져갈 때도 반드시 Free/Zeroed를 순서대로 거치지는 않습니다. 새로운 디맨드 제로 프라이빗 페이지로 사용자 모드에 넘기려면 이전 내용을 지워야 하지만, 파일 읽기 목적지처럼 페이지 전체를 덮어쓸 때는 Standby 식별만 떼고 바로 재사용할 수 있습니다.
4. Active / Valid ── 지금 참조할 수 있는 물리 페이지
Active/Valid 페이지는 유효 PTE를 통해 프로세스의 Working Set이나 시스템 공간에서 참조됩니다. CPU는 보통의 주소 변환으로 도달하므로, 그 접근 자체에는 페이지 폴트가 필요 없습니다.
그러나 페이지가 Active로 남는다는 보장은 없습니다. 메모리 관리자는 사용 가능 메모리를 유지하려고 Working Set 크기, 페이지의 최근 사용 여부 등을 보고 후보 페이지를 트리밍합니다. Microsoft의 Working Set 문서도, 메모리 관리자가 사용 가능 메모리를 만들기 위해 Working Set에서 페이지를 제거한다고 설명합니다.8
4.1. 트리밍은 해제가 아니다
Working Set 트리밍이 주로 바꾸는 것은 유효 PTE로 즉시 참조할 수 있는 상주 상태입니다. 다음 넷은 서로 다른 사건으로 구분하십시오.
- Working Set에서 빼기
- Commit 해제
- 가상 주소 범위 해제
- 원본 데이터 상실
EmptyWorkingSet이나 도구의 「Trim Working Set」를 실행하는 것은 VirtualFree나 힙 해제의 대체가 아닙니다. 같은 페이지에 다시 닿으면 Standby에서의 소프트 폴트, 또는 백킹 스토어에서의 하드 폴트로 돌아옵니다. 따라서 「Working Set를 줄였다」는 「누수를 고쳤다」를 뜻하지 않습니다.
5. clean 페이지는 Standby로 간다
페이지가 Working Set에서 빠져도, 내용이 원본 파일과 같거나 이미 안전한 백킹 스토어가 있으면 Standby에 둘 수 있습니다. 대표적인 예는 다음과 같습니다.
- 변경되지 않은 EXE/DLL 코드
- 변경되지 않은 메모리 매핑 파일
- 이미 다시 쓰인 프라이빗 페이지
- 파일 캐시에 남은 데이터
Standby 페이지는 이전 내용과의 대응을 유지합니다. 같은 프로세스나 다른 프로세스가 그 내용을 필요로 할 때, 아직 재사용되지 않았다면 PTE를 다시 연결하는 소프트 폴트만으로 복원할 수 있습니다.
반면 다른 할당이 물리 페이지를 필요로 하면, 이전 Standby 식별을 버리고 페이지를 재사용할 수 있습니다. 재사용처가 0 초기화가 필요한 사용자 모드 프라이빗 페이지면 Zeroed 페이지를 준비하고, 파일 내용으로 페이지 전체를 덮어쓸 때는 제로화 없이 바로 재할당할 수 있습니다.
이 양면성이야말로 Standby가 캐시이면서 동시에 Available인 이유입니다.
5.1. Available에 Standby가 들어가는 이유
MEMORYSTATUSEX.ullAvailPhys는 디스크에 쓰지 않고 즉시 재사용할 수 있는 물리 메모리를 나타내며, Standby, Free, Zeroed의 합입니다.1
flowchart LR
accTitle: Available을 구성하는 세 페이지 리스트
accDescr: 사용 가능 물리 메모리는 Standby, Free, Zeroed의 합이며 Working Set에서 참조 중인 Active 페이지는 포함되지 않는다
standby["Standby(내용을 유지한 재사용 후보)"] --> avail["Available(사용 가능 물리 메모리)"]
free["Free(미사용, 제로화되지 않음)"] --> avail
zeroed["Zeroed(미사용이고 제로화됨)"] --> avail
active["Active(Working Set에서 참조 중)"] -.->|포함되지 않음| avail
그림 2: Available은 Standby, Free, Zeroed의 합입니다. 내용을 아직 들고 있는 Standby도 「사용 가능」으로 셉니다.
그래서 작업 관리자에 「Free는 적은데 Cached/Standby는 많고 Available은 충분하다」고 나와도 모순이 아닙니다. Windows는 빈 RAM을 그냥 두지 않고, 최근에 쓴 파일과 코드를 Standby에 남겨 필요하면 캐시로 빠르게 재사용하고, 다른 용도가 필요하면 가져갑니다.
「Free가 적으니 당장 메모리가 부족하다」고 단정하지 말고, Available, Commit, 하드 폴트, 처리 지연을 함께 보십시오.
6. dirty 페이지는 Modified에서 기다린다
앱이 페이지에 쓰면 그 내용은 원래 백킹 스토어와 더 이상 일치하지 않습니다. 그 dirty 페이지를 다른 용도로 덮어쓰면 데이터가 사라집니다. 그래서 Working Set에서 빠진 변경 페이지는 Modified에서 다시 쓰기를 기다립니다.
다시 쓰기 목적지는 페이지 종류에 따라 달라집니다.
| 페이지 종류 | 대표적인 다시 쓰기 목적지 |
|---|---|
| 프라이빗 Commit 페이지 | 페이지 파일 |
| 쓰기 가능한 매핑 파일 | 대응 데이터 파일 |
| 파일 캐시의 dirty 데이터 | 대응 데이터 파일 |
| clean EXE/DLL 페이지 | 다시 쓰기 불필요. 원본 이미지에서 다시 읽을 수 있음 |
Microsoft의 페이지 파일 문서도, 이미 디스크에 있는 .dll, .exe, 일반 파일은 페이지 파일에 다시 쓸 필요가 없고, 원본 디스크 복사본이 없는 변경 데이터가 페이지 파일 후보가 된다고 설명합니다.2
6.1. Modified Page Writer
Modified Page Writer는 메모리 관리자가 추적하는 페이지 파일 백킹 dirty 페이지를 스캔해 페이지 파일로 내보내는 시스템 워커입니다.3 매핑 파일 쪽에는 Mapped Page Writer 같은 경로가 있어, 파일 시스템과 캐시 관리자와 협력해 대응 파일에 다시 씁니다.
여기서 중요한 점은, 내보내기가 「RAM이 0바이트가 될 때까지 아무것도 하지 않는」 방식이 아니라는 것입니다. Windows는 Modified 목록, Available, 페이지 파일 상태 등에 따라 앞으로 재사용할 수 있는 페이지를 백그라운드에서 준비합니다. 다시 쓰기가 끝나고 다른 유효 참조가 없으면, 페이지는 내용을 유지한 채 Standby로 진행합니다.
flowchart TB
accTitle: 변경 페이지의 다시 쓰기 경로
accDescr: Working Set에서 벗어난 변경 페이지는 Modified 목록에서 기다리고, 프라이빗 페이지는 페이지 파일이 구성되어 있으면 Modified Page Writer가 페이지 파일에 쓰며, 매핑 파일 페이지는 Mapped Page Writer 등이 대응 데이터 파일에 다시 쓴 뒤 내용을 유지한 채 Standby로 진행한다
dirty["Working Set에서 벗어난 변경 페이지"] --> modified["Modified 목록에서 다시 쓰기를 기다림"]
modified -->|"프라이빗 페이지(페이지 파일 구성 시)"| mpw["Modified Page Writer가 페이지 파일에 씀"]
modified -->|매핑 파일 페이지| mapped["Mapped Page Writer 등이 대응 파일에 다시 씀"]
mpw --> standby["다시 쓰기 후, 내용을 유지한 채 Standby로"]
mapped --> standby
그림 3: 다시 쓰기 목적지는 페이지 종류로 정해지고, 두 경로 모두 백그라운드에서 진행됩니다. 페이지 파일을 끈 시스템에서는 프라이빗 페이지 쪽 다시 쓰기 목적지가 없어, 변경된 프라이빗 페이지는 RAM에 남습니다.
6.2. 페이지 출력과 페이지 파일 고유 I/O를 구분하기
다음 카운터는 혼동하기 쉬우니 의미를 확인하십시오.
Memory\\Page Writes/sec: 물리 메모리를 비우려고 발행한 페이징 쓰기 I/O 횟수Memory\\Pages Output/sec: 그 쓰기로 디스크에 나간 페이지 수Memory\\Page Reads/sec: 하드 폴트를 해결하려고 발행한 디스크 읽기 I/O 횟수Memory\\Pages Input/sec: 그 읽기로 RAM에 들어온 페이지 수
Page Writes/sec와 Pages Output/sec는 페이지 파일만 가리키는 카운터가 아닙니다. 매핑 파일처럼 파일 백킹 dirty 페이지를 다시 쓰는 경로에서도 올라갈 수 있습니다. 반대로 입력 쪽도 페이지 파일, DLL, EXE, 메모리 매핑 파일을 구분하지 않습니다.2 pagefile.sys 고유 I/O를 특정하려면 이 네 카운터만으로 추정하지 말고, ETW/WPA로 File I/O와 Disk I/O를 기록한 뒤 FileObject와 FileName을 맞춰 대상 파일을 확인하십시오.9
한 가지 더, 페이지 파일에 먼저 썼다고 해서 바로 디스크에서 다시 읽는다는 뜻은 아닙니다. 페이지에 접근하지 않으면, 다시 쓴 페이지를 RAM에서 빼고 더 자주 쓰는 페이지에 물리 메모리를 줄 수 있습니다.
7. Standby, Free, Zeroed의 차이
7.1. Standby
이전 내용과의 대응을 아직 유지하는 상태입니다.
- 같은 내용이 필요하면 소프트 폴트로 돌아올 수 있음
- 다른 용도가 필요하면 이전 식별을 버리고 재사용할 수 있음
- 우선순위별 Standby 리스트가 있음
7.2. Free
이전 내용과의 유효한 대응은 사라졌고, 할당 가능한 상태입니다. 다만 페이지 안에 이전 비트 패턴이 남아 있을 수 있습니다. 사용자 모드에 그대로 넘기면 이전 프로세스의 정보가 샐 위험이 있습니다.
7.3. Zeroed
내용이 0이고, 새로운 사용자 모드 페이지로 안전하게 넘길 수 있습니다. 제1회의 디맨드 제로 폴트는 사용 가능한 Zeroed 페이지를 얻어 PTE에 묶는 대표 사례였습니다. Free에서 Zeroed로의 준비는 수요와 시스템 상태에 따라 이루어집니다.
그래서 「Free」와 「Zeroed」는 둘 다 비어 보여도, 보안과 관련된 준비 상태가 다릅니다.
8. 메모리 압축 스토어 ── RAM 안에 목적지 하나를 더 만들기
Windows 10부터 메모리 관리자는 메모리 압력이 있을 때, 자주 쓰지 않는 페이지를 바로 디스크에 쓰는 대신 RAM 안에서 압축하는 경우가 있습니다. 그 압축 페이지 모음이 압축 스토어입니다.
초기 Windows 10 구현에서는 압축 스토어가 System 프로세스의 Working Set 안에 집계되었지만, 현재 Windows에서는 디버거 프로세스 목록에 전용 Memory Compression 프로세스로 나타납니다. 따라서 현재 압축량을 조사할 때 System 프로세스의 Working Set만 따라가면 안 됩니다. 더 많은 앱을 물리 메모리에 두고 디스크 I/O를 줄인다는 목적 자체는 바뀌지 않았습니다.1011
다만 다음을 기억하십시오.
- 압축된 페이지도 RAM을 씀
- 압축과 해제에는 CPU 비용이 있음
- 압축은 Commit 약속을 지우지 않음
- 「항상 압축한 다음 페이지 파일」이라는 고정 순서는 없음
- 페이지 종류, 압력, 접근 이력에 따라 정책이 바뀜
작업 관리자의 「사용 중(압축됨)」은 압축이 물리 메모리를 완전히 비웠다는 뜻이 아닙니다. 압축 스토어는 페이지 파일을 불필요하게 만드는 기능이 아니라, RAM과 스토리지 사이에 CPU를 써서 I/O를 줄이는 선택지를 하나 더한 것입니다.
9. 페이지 파일의 진짜 역할
페이지 파일에는 적어도 세 가지 역할이 있습니다.
flowchart LR
accTitle: 페이지 파일의 세 가지 역할
accDescr: 페이지 파일은 Commit Limit을 넓히고, 접근 빈도가 낮은 변경 프라이빗 페이지의 백킹 스토어가 되며, 시스템 크래시 덤프의 받침대가 된다
pagefile["페이지 파일"] --> limit["Commit Limit을 넓힘(상한 쪽 여유)"]
pagefile --> backing["변경된 프라이빗 페이지의 백킹 스토어"]
pagefile --> dump["시스템 크래시 덤프의 받침대"]
그림 4: 페이지 파일의 역할은 「느린 RAM」만이 아닙니다. 사용량이 0이어도 상한과 덤프를 뒷받침합니다.
9.1. Commit Limit을 넓히기
시스템의 Commit Limit은 대략 RAM과 모든 페이지 파일의 합으로 정해집니다. 페이지 파일이 없으면 Commit Limit은 탑재 RAM보다 조금 작은 수준으로 내려갑니다. Commit Total이 천장에 닿으면 새 Commit이 실패하고, 앱 비정상 종료나 시스템 문제로 이어질 수 있습니다.4
이는 「지금 pagefile.sys에 몇 GB가 쓰여 있는가」와는 다른 이야기입니다. 페이지 파일은 Commit 약속을 뒷받침하는 상한 쪽 여유이기도 합니다.
9.2. 변경된 프라이빗 페이지를 뒷받침하기
접근 빈도가 낮은 변경 프라이빗 페이지를 페이지 파일이 뒷받침하면, 그 물리 페이지를 RAM에서 빼 자주 쓰는 코드와 데이터에 줄 수 있습니다.4 페이지 파일을 끄면 그런 페이지를 RAM에서 빼는 선택지가 줄어듭니다. 「페이지 아웃이 없으니 빠르다」고 단순하게 말할 수 없습니다.
9.3. 시스템 크래시 덤프를 뒷받침하기
시스템 크래시에서 Memory.dmp를 만들려면, 선택한 덤프 방식을 뒷받침할 수 있는 페이지 파일이나 전용 덤프 파일이 필요합니다.2 전체 메모리 덤프, 커널 메모리 덤프, 자동 메모리 덤프는 필요량이 다릅니다.
크래시를 조사하는 환경에서 공간 절약만을 이유로 페이지 파일을 지우면, 가장 필요할 때 증거가 없을 수 있습니다. 수집 방법은 「Windows 앱의 크래시 덤프 수집 입문 - 우선 WER / ProcDump / WinDbg를 어떻게 구분해서 쓸까」도 보십시오.
10. 적정 크기는 일률적이지 않다
「RAM의 1.5배」 같은 고정식만으로 페이지 파일 크기를 정해서는 안 됩니다. Microsoft는 적정 크기가 다음 두 점에서 시스템마다 다르며 일반화할 수 없다고 설명합니다.2
- 피크 System Commit Charge
- 필요한 시스템 크래시 덤프
실무에서는 다음 순서로 생각합니다.
10.1. 시스템 관리를 기준으로 시작하기
Windows 기본값은 시스템 관리입니다. 탑재 RAM, Commit 수요, 크래시 덤프 요구 등에 따라 늘고 줄어듭니다. 특별한 제약이나 측정 결과가 없다면 여기서 시작하는 것이 안전합니다.
10.2. 대표 부하에서 피크 Commit을 측정하기
PerfMon에서 다음 카운터를 장기간 수집합니다.
Memory\\Committed BytesMemory\\Commit LimitMemory\\% Committed Bytes In UseMemory\\Modified Page List BytesPaging File(*)\\% UsageMemory\\Available MBytesMemory\\Page Reads/secMemory\\Page Writes/sec
수집 기간에는 월말 처리, 백업, 빌드, 여러 사용자 동시 이용처럼 실제 피크를 넣으십시오.
페이지 파일 사용률이 높다는 것만으로 스토리지 성능 문제라고 단정할 수는 없습니다. 다만 천장에 달라붙는 것은 용량 부족 경고입니다. Commit이 천장에 다가가는지, Modified가 많이 기다리는지, 디스크가 포화인지 함께 보십시오.2
10.3. 덤프 요구를 먼저 정하기
전체 메모리 덤프가 필요한지, 커널 메모리 덤프로 충분한지, 전용 덤프 파일을 쓸지 정하십시오. 고정 크기로 바꾸면 피크 Commit뿐 아니라 덤프 요구도 충족해야 합니다.
11. 직접 확인해 보기
11.1. RAMMap에서 페이지 리스트 보기
관리자로 RAMMap을 시작하고 먼저 Use Counts를 여십시오.7 볼 항목은 다음과 같습니다.
- Active
- Standby
- Modified
- Modified no write
- Free
- Zeroed
Priority Summary에서는 Standby가 우선순위별로 나뉘어 있음을 확인할 수 있습니다. Processes는 각 프로세스의 Working Set를, File Summary와 File Details는 RAM에 있는 파일 데이터를 따라가게 합니다.
시험으로 꽤 큰 로컬 파일을 한 번 읽고, 읽기를 끝낸 뒤 Refresh해 보십시오. 그 파일의 페이지가 File Summary나 Standby 쪽에 남아 있을 수 있습니다. 같은 파일을 다시 읽으면, 아직 재사용되지 않은 페이지는 디스크 I/O 없이, 또는 적은 I/O로 복원될 수 있습니다. 메모리 압력, 백신, 파일 크기에 따라 결과가 달라지니, 한 번의 숫자보다 상태 전이의 방향을 보십시오.
RAMMap의 Empty 메뉴는 시스템 상태를 인위적으로 바꿉니다. 운영 성능 개선으로 Standby를 비우지 말고, 격리된 테스트 환경에서만 쓰십시오.
11.2. Testlimit으로 Commit과 Touch 구분하기
Testlimit은 메모리, 핸들, 프로세스, 스레드 등의 리소스 부족을 흉내 내는 Sysinternals 도구입니다. 먼저 가지고 있는 바이너리에서 다음을 실행해, 표시되는 버전과 사용법을 확인하십시오.
.\\testlimit64.exe -?
다음은 Testlimit v5.24를 대상으로 합니다. 공식 v5.24 구문에서 -m [MB]는 지정량 메모리 할당, -d [MB]는 할당과 Touch, -e [seconds]는 할당 간격, -c [count]는 할당 횟수입니다. -c는 마지막에 지정합니다. 로컬 표시가 다르면 그 사용법을 우선하십시오.12
다음으로 일회용 VM에서 작게 시험합니다.
# -m 64: 64 MiB 할당, -e 1: 1초 간격, -c 8: 8회 후 중지
.\\testlimit64.exe -m 64 -e 1 -c 8
# 같은 횟수와 간격으로, -d로 각 영역을 Touch
.\\testlimit64.exe -d 64 -e 1 -c 8
실행 중에는 다음을 동시에 기록하십시오.
- 작업 관리자의 「커밋됨 X/Y」
- RAMMap의 Active, Modified, Standby
Memory\\Committed BytesMemory\\Commit LimitMemory\\Available MBytesMemory\\Modified Page List Bytes
Commit 고갈을 실제로 재현할 때는 호스트 PC에서 하지 말고, 스냅샷을 뜬 VM에서 횟수를 단계적으로 늘리십시오. 천장까지 자동 할당하는 실행은 화면 정지, 프로세스 비정상 종료, 로그 손실을 일으킬 수 있습니다. 목적은 OS를 불안정하게 만드는 것이 아니라, Commit Limit에 다가가면 새 Commit이 실패한다는 것을 관찰하는 것입니다.
12. 실무에서 피해야 할 네 가지 오해
12.1. 「Standby가 많으니 메모리 누수」
Standby는 재사용 가능한 캐시이며 Available에 포함됩니다. 누수는 부하가 끝난 뒤에도 프로세스 전용 Commit 기준선과 할당 내역이 계속 늘어나는지로 판단하십시오.
12.2. 「Working Set를 줄이면 누수가 고쳐진다」
트리밍은 상주 상태만 바꾸고, Commit이나 가상 할당을 해제하지 않습니다. 다시 접근하면 페이지가 폴트로 돌아옵니다.
12.3. 「페이지 파일 사용량이 0이니 필요 없다」
페이지 파일은 현재 쓰기량뿐 아니라 Commit Limit과 크래시 덤프도 뒷받침합니다. 일상 사용량만으로 삭제하면 피크 여유와 장애 시 증거를 잃습니다.
12.4. 「메모리 압축이 먼저, 그다음 항상 페이지 파일」
압축은 고정된 직렬 파이프라인이 아닙니다. Windows는 페이지 종류, 압축 효율, CPU 부하, 메모리 압력, 백킹 스토어 유무에 따라 동적으로 고릅니다.
13. 정리
- PFN 데이터베이스는 물리 페이지의 소유, 참조, 변경, 페이지 리스트 상태를 추적하는 대장입니다.
- Working Set에서 벗어난 clean 페이지는 Standby에 남아, 같은 내용이 필요하면 소프트 폴트로 돌아올 수 있습니다.8
- dirty 페이지는 Modified에서 기다리고, 프라이빗이면 페이지 파일에, 매핑이면 대응 파일에 다시 쓰입니다.3
- Available은 Standby, Free, Zeroed의 합이며, Standby가 많다는 것만으로 메모리 부족이 아닙니다.1
- 메모리 압축은 RAM 안에서 페이지를 압축해 I/O를 줄이지만, Commit과 페이지 파일의 역할을 지우지 않습니다.10
- 페이지 파일은 Commit Limit, 변경된 프라이빗 페이지, 시스템 크래시 덤프를 뒷받침합니다.42
- 적정 크기는 피크 Commit과 덤프 요구로 정해지며, 일률적인 배수로는 정할 수 없습니다.2
- Working Set 트리밍과 Standby 비우기는 메모리 누수 수정이 아닙니다.
이어지는 제3회는 「섹션 객체와 복사 온 라이트: DLL과 파일 매핑의 정체」입니다.
Standby에 남은 파일 페이지와 DLL이 여러 프로세스에서 왜 같은 물리 페이지로 보이는지를 따라갑니다.
관련 기사
- Windows 메모리의 심층(제1회) ── 가상 주소가 물리 RAM이 되는 순간
- Windows의 「메모리 사용량」은 무엇을 나타내는가 ── Working Set·Private Bytes·Commit·페이지 파일을 올바르게 읽는 법
- Windows I/O의 심층(제4회) ── 캐시 관리자: 당신의 WriteFile은 언제 디스크에 도달하는가
- Windows 앱의 크래시 덤프 수집 입문 - 우선 WER / ProcDump / WinDbg를 어떻게 구분해서 쓸까
- Process Explorer / Handle / VMMap 실전 ── 행(hang)・누수・「파일 사용 중」을 지금 이 순간의 상태에서 추적한다
관련 상담 영역
합동회사 코무라소프트는 Windows 애플리케이션의 메모리 압력, Commit 고갈, 페이징, Working Set 증가, 크래시 덤프 수집 설계 조사를 다룹니다.
참고 링크
-
Microsoft Learn, MEMORYSTATUSEX structure.
ullAvailPhys가 디스크에 쓰지 않고 즉시 재사용할 수 있는 물리 메모리이며 Standby, Free, Zeroed 리스트의 합이라는 점에 대해. ↩ ↩2 ↩3 -
Microsoft Learn, How to determine the appropriate page file size for 64-bit versions of Windows. 적정 크기가 피크 Commit과 크래시 덤프 요구에 따라 달라 일반화할 수 없다는 점, Modified 목록, 페이지 파일 사용률, 관련 카운터, 시스템 관리 페이지 파일에 대해. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Data corruption on IO write. Modified Page Writer가 페이지 파일 백킹 dirty 페이지를 스캔해 내보내는 메모리 관리자 시스템 워커라는 점에 대해. ↩ ↩2 ↩3
-
Microsoft Learn, Introduction to page files. 페이지 파일이 접근 빈도가 낮은 변경 페이지를 RAM에서 빼고, Commit Limit을 넓히고, 시스템 크래시 덤프를 뒷받침하는 점에 대해. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, !pfn (WinDbg). 지정한 PFN 항목의 상태, 참조, PTE 주소 등을 표시할 수 있는 점에 대해. ↩
-
Microsoft Learn, !memusage (WinDbg). 물리 메모리 사용량과 Zeroed, Free, Standby, Modified, Active 같은 페이지 상태를 집계할 수 있는 점에 대해. ↩
-
Microsoft Learn, RAMMap - Sysinternals. RAMMap의 Use Counts, Processes, Priority Summary, Physical Pages, File Summary, File Details가 물리 메모리 용도와 페이지 리스트를 표시하는 점에 대해. ↩ ↩2
-
Microsoft Learn, Working Set. 메모리 관리자가 사용 가능 메모리를 만들기 위해 Working Set를 트리밍하는 점, Transition이나 다른 프로세스의 Working Set에 남은 페이지를 소프트 폴트로 해결할 수 있는 점에 대해. ↩ ↩2
-
Microsoft Learn, FileIo_Name class. ETW File I/O 이벤트에 FileObject와 FileName이 있어 FileObject를 Disk I/O 이벤트와 맞춰 대상 파일 I/O를 식별할 수 있는 점에 대해. ↩
-
Windows Insider Blog, Announcing Windows 10 Insider Preview Build 10525. 초기 Windows 10 압축 스토어 구현이 RAM 안 압축 페이지 모음을 System 프로세스 Working Set에 두고 디스크 쓰기를 줄인 점에 대해. ↩ ↩2
-
Microsoft Learn, Find Process ID (PID) in Windows. 현재 Debugging Tools for Windows 프로세스 목록 예에 System 아래 별도 PID의
Memory Compression프로세스가 나타나는 점에 대해. ↩ -
Microsoft Learn, Testlimit - Sysinternals. Testlimit v5.24 공식 구문에서
-m이 메모리 할당,-d가 할당과 Touch,-e가 할당 간격,-c가 할당 횟수이며-c를 마지막에 지정하는 점에 대해. ↩
관련 기사
같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.
Windows의 「메모리 사용량」은 무엇을 나타내는가 ── Working Set·Private Bytes·Commit·페이지 파일을 올바르게 읽는 법
작업 관리자의 메모리, Working Set, Private Bytes, Commit은 같은 값이 아닙니다. Windows의 가상 메모리와 물리 메모리의 관계, 페이지 파일의 역할, 메모리 부족이나 누수 조사에서 봐야 할 지표를 설명합니다.
Windows 메모리의 심층(제1회) ── 가상 주소가 물리 RAM이 되는 순간: 페이지 폴트의 처음부터 끝까지
VirtualAlloc, VAD, 페이지 테이블, TLB, 디맨드 제로, 하드 폴트를 이어서 가상 주소에 물리 RAM이 붙는 순간을 설명합니다.
Windows 메모리의 심층(제3회) ── 섹션 객체와 복사 시 쓰기: DLL과 파일 매핑의 정체
섹션 객체, 이미지·데이터 매핑, 공유 캐시, 복사 시 쓰기를 연결해 DLL과 공유 메모리가 물리 페이지를 어떻게 공유하는지 설명합니다.
Windows 가상화의 심층(제3회) ── 수초 만에 기동하는 가상 머신: WSL2, Windows Sandbox, 컨테이너가 가벼운 이유
WSL2와 Windows Sandbox가 수초 만에 기동하고 가벼운 이유는 무엇일까요. 동적 베이스 이미지와 다이렉트 맵, 동적 메모리 할당부터 Hyper-V 격리 컨테이너까지 구조를 해설합니다.
Windows 가상화의 심층(제2회) ── 커널에서도 보이지 않는 메모리: VBS, HVCI, Credential Guard의 구조
호환 하드웨어에 대한 클린 설치에서 기본으로 켜지는 VBS는, 하이퍼바이저와 SLAT로 커널보다 강한 격리를 만듭니다. VTL, Secure Kernel, HVCI, Credential Guard의 구조를 해설합니다.
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
Windows 앱 개발
상주 처리, 장비 연동, 운영 로그, 유지 보수 가능한 구조가 필요한 Windows 데스크톱 애플리케이션을 지원합니다.
자주 묻는 질문
이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.
- Working Set에서 벗어난 페이지는 바로 페이지 파일에 쓰이나요?
- 아닙니다. 변경되지 않은 페이지는 내용을 유지한 채 Standby로 옮겨 즉시 재사용할 수 있는 캐시가 됩니다. 변경된 페이지는 Modified로 옮겨, 필요에 따라 페이지 파일이나 대응 파일에 다시 쓰인 뒤 Standby 같은 재사용 가능 상태로 진행합니다.
- 작업 관리자의 Available에 Standby 메모리가 포함되나요?
- 포함됩니다. Windows가 보고하는 사용 가능 물리 메모리는 Standby, Free, Zeroed의 합입니다. Standby는 이전 내용을 아직 들고 있지만, 필요하면 바로 다른 용도로 재사용할 수 있어 사용 가능 메모리로 셉니다.
- 페이지 파일에 쓰는 작업은 RAM이 완전히 바닥난 뒤에야 시작하나요?
- 아닙니다. Windows는 Modified 목록과 사용 가능 메모리 상태에 따라, 접근 빈도가 낮은 변경 페이지를 백그라운드에서 다시 씁니다. 절대적 고갈을 기다렸다가 한꺼번에 쫓아내는 단순한 메커니즘이 아닙니다.
- 페이지 파일을 끄면 Windows가 빨라지나요?
- 일반적으로 그렇다고 단정할 수 없습니다. 끄면 Commit Limit이 내려가고, 접근 빈도가 낮은 변경 페이지를 RAM에서 빼기 어려워지며, 시스템 크래시 덤프에도 영향을 줍니다. 보통은 시스템 관리로 두고, 피크 Commit과 덤프 요구를 측정해 판단합니다.
- 메모리 압축이 있으면 페이지 파일은 필요 없나요?
- 필요 없어지지 않습니다. 압축 스토어는 RAM 안에서 페이지를 압축해 I/O를 줄이지만, 압축된 페이지도 물리 메모리를 쓰고 Commit 보증을 대체하지 않습니다. 압축과 페이지 아웃의 선택은 메모리 관리자의 동적 정책입니다.