-
Notifications
You must be signed in to change notification settings - Fork 0
Cleanup Areas
"메모리를 정리한다"는 말은 실제로는 여섯 가지 서로 다른 동작이다. 각각 회수량·부작용·필요 권한이 다르므로, 하나씩 켜고 끌 수 있게 해 두었다. 기본값은 안전 우선(① ②만 켜짐)이다.
Windows의 Available은 사용 가능 = 대기(Standby) + 여유(Free) + 0으로 채운(Zeroed)이다.
여기서 흔한 오해가 하나 있다.
대기 목록을 비워도 Available은 늘지 않는다. 대기 페이지는 이미 Available에 포함돼 있기 때문이다. 퍼지는 "캐시를 버리는" 동작이지 "여유를 만드는" 동작이 아니다. 반대로 워킹셋 트림은 실제로 Available을 늘린다 — 프로세스가 붙들고 있던 페이지를 대기 목록으로 내려놓기 때문이다.
이 도구가 알림에 표시하는 회수량은 정리 전후의 Available 차이다.
⚠️ 다만 이 숫자를 "얼마나 빨라졌나"로 읽으면 안 된다. 실측해 보니 표시 +679MB일 때 실제로 걷힌 워킹셋은 3,870MB였다(차액은 Available에 안 잡히는 수정 목록으로 이동). 반대로 영역 ③처럼 캐시를 버리는 동작은 표시값을 부풀리면서 체감은 깎는다. 자세한 측정 → 효용성
| # | 영역 | 하는 일 | 권한 | 부작용 |
|---|---|---|---|---|
| ① | 프로세스 워킹셋 트림 | 각 프로세스가 붙들고 있는 물리 페이지를 대기 목록으로 내려놓는다 | 일반(자기 세션) | 해당 앱이 다시 활성화될 때 약간의 재적재 |
| ② | 우선순위 0 대기 퍼지 | 가장 낮은 우선순위의 대기 페이지만 버린다 | 관리자 | 거의 없음 — 어차피 가장 먼저 버려질 페이지 |
| ③ | 전체 대기 퍼지 | 대기 목록 전체를 버린다 | 관리자 | 파일 캐시가 사라진다 — 이후 디스크 읽기 증가 |
| ④ | 수정 페이지 플러시 | 변경된 페이지를 디스크에 기록하고 정리 | 관리자 | 디스크 쓰기 발생 |
| ⑤ | 시스템 워킹셋 비우기 | 커널·드라이버가 쥔 워킹셋을 내려놓는다 | 관리자 | 캐시 재적재 비용 |
| ⑥ | 페이지 결합 | 내용이 같은 물리 페이지를 하나로 합친다 | 관리자 권장 | 수 초 소요, 효과는 완만 |
기본 켜짐: ① ②. 나머지는 필요할 때 설정에서 켠다.
- ①
K32EmptyWorkingSet(프로세스별) - ② ~ ⑤
NtSetSystemInformation(SystemMemoryListInformation)— RAMMap(Microsoft Sysinternals)과 같은 경로 - ⑥
NtSetSystemInformation(SystemCombinePhysicalMemoryInformation)— 커널이 합친 페이지 수를 돌려준다
②~⑥은 문서화되지 않은 NT API지만 Windows 7 이후 십수 년째 안정적이고, Microsoft 자신의 도구가 같은 경로를 쓴다. 그래도 실패를 성공으로 위장하지 않는다 — 실패한 영역은 알림에 명시된다.
| 모드 | 결과 |
|---|---|
| 일반 실행 | 트림 115개 성공 / 378개 제외 · 영역 ② 0xC0000061(권한 없음)로 실패 → 부분 성공 · 회수 +322MB
|
| 관리자 승격 | 트림 466개 / 25개 제외 · 영역 ② 성공 · 회수 +847MB (약 2.6배) |
📌 관리자 권한은 필수가 아니다. 일반 권한으로도 관찰·목록·자기 세션 트림이 모두 되고 실제로 회수된다(위 +322MB). 승격은 "더 많이 회수"를 위한 선택지이며, 필요할 때 트레이 메뉴의 **[관리자 권한으로 재시작]**을 쓰면 된다(UAC 1회).
자동 실행은 항상 일반 권한으로 시작한다 — Windows가 HKCU\...\Run 항목의 승격을 허용하지 않기
때문이다. 승격된 자동 시작이 필요하면 작업 스케줄러에 "가장 높은 권한으로 실행"으로 등록해야 한다.
문서상 관리자 권한이 필요하다고 알려져 있으나, 일반 권한에서도 성공했다(Windows 11 26200 실측): 349MB 결합, Available 3825MB → 4190MB(+365MB). 다만 수 초가 걸리므로 기본은 꺼 두었다.
| 트리거 | 조건 | 기본값 |
|---|---|---|
| 임계값 | 사용률이 기준을 넘으면 | 90% |
| 주기 | 일정 시간마다 | 꺼짐 |
| 저메모리 이벤트 |
Windows가 부족을 알릴 때 (LowMemoryResourceNotification) |
켜짐 |
세 트리거 모두 쿨다운(기본 5분)을 공유한다. 특히 저메모리 이벤트는 부족 상태가 한동안 계속 켜져 있기 때문에, 쿨다운이 없으면 폴링마다 정리가 반복된다.
이벤트 감지는 대기 스레드를 쓰지 않는다. 알림 핸들을 하나 만들어 두고 기존 폴링 때마다 상태만 물어본다 — 스레드 하나가 유휴 예산을 갉아먹는 것보다, 커널 플래그를 읽는 질의 한 번이 훨씬 싸다.
- 시스템 필수 프로세스는 목록 단계에서 제외된다 — 종료·트림 대상으로 아예 노출되지 않는다.
- 회수는 항상 워커 프로세스에서 수행된다. 워커가 죽어도 트레이 셸은 살아 있다.
- 프로세스 종료는
WM_CLOSE→ 3초 대기 → 강제 종료의 2단계.
Nexa MemKeeper · SosomLab · PolyForm Noncommercial 1.0.0 — 개인·비상업 무료, 상업 사용은 별도 라이선스(kiros33@sosomlab.com)