Windows Sysinternals 에서 제공하는 TestLimit 이라는 도구에 대해서 소개해 봅니다. 이 도구는 Windows Internals 환경을 테스트 하기 위해 프로세스에 대해 다양한 유형의 Memory Leak 을 일으킬 수 있고 handles, threads 를 생성할 수 있으며 USER Desktop heap 소진 등의 기능을 가지고 있습니다. 이 중에서 메모리 누수와 관련하여 몇 가지 테스트를 통해 사용 방법을 확인하였습니다.

"/3GB 스위치를 사용했는데 정말 프로스세가 2GB 이상 메모리를 사용하는지 확인할 수 있을까?" 궁금하시다면 테스트를..."


[환경]
Windows Server 2003 SP2 (x86)
Physical Memory : 4GB / Paging File 2~4GB 


testlimit 툴의 도움말은 다음과 같습니다.




wmic 명령으로 32bit 운영체제에서 사용할 수 있는 최대 프로세스 메모리 사이즈를 확인해 봅니다. /3GB 옵션을 사용하지 않은 환경입니다. 

wmic:root\cli> path win32_operatingsystem get MaxProcessMemorySize 





-d 스위치를 사용하여 카운트를 설정하지 않고 최대로 testlimit.exe 프로세스의 private bytes 를 증가시키고 commit 시킬 때, 2028 MB 이상 늘어날 수 없다는 오류가 발생합니다.




다음은 4가지 유형별로 memory leak 또는 reserved 하여 작업 관리자 또는 커널 디버그를 통해 상태를 확인하였습니다.


[Leaking private bytes with touch]
-d 스위치를 사용하여 Private bytes 를 1MB 단위로 commit 하며 증가시키는 데, 할당 개수를 2028개로 지정합니다.

C:\TestLimit> testlimit -d -c 2028





작업 관리자를 통해 확인해 보면, 메모리 사용, VM 크기 모두 증가하였습니다. 





[Leaking private bytes]
-m 스위치를 사용하여 Private bytes 를 1MB 단위로 증가시키는 데, 할당 개수를 2028개로 지정합니다.

C:\TestLimit> testlimit -m -c 2028




작업 관리자로 확인해 보면 VM 크기만 증가한 것을 확인할 수 있습니다. 



커널 모드 디버그를 통해 해당 프로세스 상태를 확인해 보면 Working Set size 와 Virtual Size 를 비교할 수 있습니다.

lkd> !process 0e6c

Searching for Process with Cid == e6c

Cid Handle table at e1230000 with 524 Entries in use

PROCESS 8a925460  SessionId: 0  Cid: 0e6c    Peb: 7ffd9000  ParentCid: 08cc

    DirBase: f6b5e440  ObjectTable: e212eb30  HandleCount:  20.

    Image: Testlimit.exe

    VadRoot 8aad0520 Vads 2064 Clone 0 Private 61. Modified 0. Locked 0.

    DeviceMap e17925c0

    Token                             e2133d10

    ElapsedTime                       00:00:14.246

    UserTime                          00:00:00.000

    KernelTime                        00:00:00.000

    QuotaPoolUsage[PagedPool]         29036

    QuotaPoolUsage[NonPagedPool]      82560

    Working Set Sizes (now,min,max)  (373, 50, 345) (1492KB, 200KB, 1380KB)

    PeakWorkingSetSize                373

    VirtualSize                       2041 Mb

    PeakVirtualSize                   2041 Mb

    PageFaultCount                    382

    MemoryPriority                    BACKGROUND

    BasePriority                      8

    CommitCharge                      520261




[Reserving private bytes]
-r 스위치를 사용하여 Reserved memory를 증가합니다.

C:\TestLimit> testlimit -r -c 2028



Virtual Size 는 할당되었지만 commit charge 는 늘어나지 않습니다.



 
CommitCharge 값을 확인하여 Committed VM Size (1093*4) = 4372KB 를 확인할 수 있습니다.

lkd> !process 0a88
Searching for Process with Cid == a88
Cid Handle table at e1230000 with 552 Entries in use
PROCESS 8a1fd538  SessionId: 0  Cid: 0a88    Peb: 7ffd9000  ParentCid: 08cc
    DirBase: f6b5e440  ObjectTable: e1a85130  HandleCount:  20.
    Image: Testlimit.exe
    VadRoot 8a880100 Vads 2064 Clone 0 Private 61. Modified 0. Locked 0.
    DeviceMap e17925c0
    Token                             e742c030
    ElapsedTime                       00:00:57.102
    UserTime                          00:00:00.000
    KernelTime                        00:00:00.015
    QuotaPoolUsage[PagedPool]         29036
    QuotaPoolUsage[NonPagedPool]      82560
    Working Set Sizes (now,min,max)  (374, 50, 345) (1496KB, 200KB, 1380KB)
    PeakWorkingSetSize                374
    VirtualSize                       2041 Mb
    PeakVirtualSize                   2041 Mb
    PageFaultCount                    383
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      1093 


 

[Leaking shared memory]
 
-s 스위치를 사용하여 shared memroy 를 증가합니다.

C:\TestLimit> testlimit -s



Physical Memory(4GB) + Paging File(2~4GB) 을 합한 전체 메모리 한도까지 공간 할당을 시도하고 있습니다. 



이 상태에선 리소스 부족으로 작업 관리자를 실행할 수 없을 수도 있습니다. 커널 모드 디버그를 통해 확인 결과 Shared Commit 에 의해 Committed pages 가 limit 까지 리소스를 사용하고 있음을 확인할 수 있습니다. 

lkd> !vm 4

*** Virtual Memory Usage ***
Physical Memory:     1048388 (   4193552 Kb)
Page File: \??\C:\pagefile.sys
 Current:   4190208 Kb  Free Space:   4177300 Kb
 Minimum:   2095104 Kb  Maximum:      4190208 Kb
Available Pages:      943285 (   3773140 Kb)
ResAvail Pages:       966621 (   3866484 Kb)
Locked IO Pages:         370 (      1480 Kb)
Free System PTEs:     190751 (    763004 Kb)
Free NP PTEs:          32766 (    131064 Kb)
Free Special NP:           0 (         0 Kb)
Modified Pages:          125 (       500 Kb)
Modified PF Pages:       125 (       500 Kb)
NonPagedPool Usage:     3326 (     13304 Kb)
NonPagedPool Max:      65308 (    261232 Kb)
PagedPool 0 Usage:     12514 (     50056 Kb)
PagedPool 1 Usage:       821 (      3284 Kb)
PagedPool 2 Usage:       808 (      3232 Kb)
PagedPool Usage:       14143 (     56572 Kb)
PagedPool Maximum:     90624 (    362496 Kb)
Shared Commit:       1985371 (   7941484 Kb)
Special Pool:              0 (         0 Kb)
Shared Process:         2959 (     11836 Kb)
PagedPool Commit:      14176 (     56704 Kb)
Driver Commit:          1290 (      5160 Kb)
Committed pages:     2052677 (   8210708 Kb)
Commit limit:        2054136 (   8216544 Kb)



[참고자료]
TestLimit
http://download.sysinternals.com/Files/Testlimit.zip


작성자 : Lai Go / 작성일자 : 2011.08.04 
Posted by Lai Go