Pool 부족시 유용한 명령어들
메모리 할당 관련 에러가 발생할 경우 찾아볼 수 있는 명령
Server 운영체제에서 Kernel Module 을 개발하다 보면 메모리 할당에 실패하는 경우가 간혹 나타난다. 이때 어떤 Module 이 메모리를 많이 사용하는지 아니면 다른 것 때문에 메모리 할당이 실패하는지 구분하기 힘들때가 있다. 이때 유용한 몇가지 명령을 알아보자.
!vm Virtual memory 의 현황을 알려준다. 메모리 부족 현상이 발생하였을 경우 우선적으로 !vm 명령을 실행하여 Free 메모리의 상태를 확인해 보아야 한다.
1) Kernel Module 이 Load 되지 않는 다면 Free System PTEs 를 확인해 보아야 한다. Kernel Module 이 Load 될 공간과 Stack 공간등이 할당되는 영역인데 5000 이하로 떨어지면 Kernel Module 이 Load 되지 않는다. User Mode Memory 를 3GB로 설정 하였을 경우 이 공간이 부족하게될 가능성이 높다.
2) NonPagedPool, PagedPool 이 할당되지 않는다면 할당이 실패할 때마다 pool allocations have failed 값이 1씩 증가하게 된다. NonPagedPool Usage 와 Max 값 그리고 PagedPool Usage 와 Max 값을 비교해 보고 현재의 할당량을 확인해 보아 메모리가 부족한지 확인해야 한다.
- Max 에 가깝게 Pool 을 사용하고 있다면 !poolused, !pool 등의 명령을 통해 어떤 Tag을 사용하는 Kernel Module 이 Pool 을 많이 사용하는지 확인해 봐야 한다.
- 남아있는 메모리는 있는데 할당이 되지 않는다면 !pool 명령으로 pool 이 단편화 되었는지 확인해 보아야 한다. (아직 단편화가 원인인지는 확인되지 않았으나 pool 단편화로 인해서 free 로 되어 있는 pool 보다 큰 크기의 pool 할당은 실패하는 것으로 생각된다.kd> !vm 1
*** Virtual Memory Usage ***
Physical Memory: 16270 ( 65080 Kb)
Page File: \??\E:\pagefile.sys
Current: 98304Kb Free Space: 61044Kb
Minimum: 98304Kb Maximum: 196608Kb
Available Pages: 5543 ( 22172 Kb)
ResAvail Pages: 6759 ( 27036 Kb)
Locked IO Pages: 112 ( 448 Kb)
Free System PTEs: 45089 ( 180356 Kb)
Free NP PTEs: 5145 ( 20580 Kb)
Free Special NP: 336 ( 1344 Kb)
Modified Pages: 714 ( 2856 Kb)
NonPagedPool Usage: 877 ( 3508 Kb)
NonPagedPool Max: 6252 ( 25008 Kb)
PagedPool 0 Usage: 729 ( 2916 Kb)
PagedPool 1 Usage: 432 ( 1728 Kb)
PagedPool 2 Usage: 436 ( 1744 Kb)
PagedPool Usage: 1597 ( 6388 Kb)
PagedPool Maximum: 13312 ( 53248 Kb)
********** 4270 pool allocations have failed **********
Shared Commit: 1097 ( 4388 Kb)
Special Pool: 229 ( 916 Kb)
Shared Process: 1956 ( 7824 Kb)
PagedPool Commit: 1597 ( 6388 Kb)
Driver Commit: 828 ( 3312 Kb)
Committed pages: 21949 ( 87796 Kb)
Commit limit: 36256 ( 145024 Kb)
!fraq
NonPagedPool 이 얼마나 사용되고 단편화 되었는지 알려준다.
kd> !frag 1
NonPaged Pool Fragmentation
index: 0 number of fragments: 4 bytes: 128
index: 1 number of fragments: 0 bytes: 0
index: 2 number of fragments: 2 bytes: 192
index: 3 number of fragments: 0 bytes: 0
...
index: 20 number of fragments: 0 bytes: 0
index: 21 number of fragments: 0 bytes: 0
index: 22 number of fragments: 1 bytes: 7232
index: 23 number of fragments: 0 bytes: 0
index: 24 number of fragments: 0 bytes: 0
Number of fragments: 11 consuming 9344 bytes
NonPagedPool Usage: 1105920 bytes
!poolused
Gflags 를 사용해서 Pool Tag 를 활성화 시켜야 한다. (Windows 2003 이후에는 기본이 활성화) PagedPool 이나 NonPagedpool 할당이 실패할 경우 이 명령으로 Pool 의 사용량을 확인해야 한다. 현재 Pool 의 사용량을 Tag 를 기준으로 보여준다. 어떤 Tag 가 Pool 을 많이 사용하는지를 알아내고 어떤 Kernel Module 이 해당 Tag 를 사용하는지 확인하여 원인 제공 Module 을 찾을 수 있다.
0: kd> !poolused
Sorting by Tag
Pool Used:
NonPaged Paged
Tag Allocs Used Allocs Used
1394 1 520 0 0UNKNOWN pooltag '1394', please update pooltag.txt
1MEM 1 3368 0 0UNKNOWN pooltag '1MEM', please update pooltag.txt
2MEM 1 3944 0 0UNKNOWN pooltag '2MEM', please update pooltag.txt
....
thdd 0 0 1 20480DirectDraw/3D handle manager table
usbp 18 77056 2 96UNKNOWN pooltag 'usbp', please update pooltag.txt
vPrt 0 0 18 68160UNKNOWN pooltag 'vPrt', please update pooltag.txt
TOTAL 3570214 209120008 38769 13066104
!pool
특정 Pool 이나 System-wide 한 Pool 의 정보를 볼 수 있다. 특정 Pool 의 경우 해당 Pool 에 할당된 Tag 를 볼 수 있으며 System-Wide 의 경우 전체 Pool 영역중 할당된 것과 아직 할당되지 않은 영역을 알 수 있다. Pool 단편화가 발생하여 적당한 크기의 free pool 이 없을 경우 큰 크기의 pool 할당이 실패할 수 있다.
kd> !pool e1001050
e1001000 size: 40 previous size: 0 (Allocated) MmDT
e1001040 size: 10 previous size: 40 (Free) Mm
*e1001050 size: 10 previous size: 10 (Allocated) *ObDi
lkd> !pool
Paged Pool: e1000000 .. f73fffff
e1000000: 1000 - busy
e1001000: 1000 - busy
e1002000: 1000 - busy
e1003000: 1000 - busy
e1004000: 1000 - busy
e1005000: 1000 - busy
...
e7032000: d000 - busy
e703f000: 22000 - busy
e7061000: 8000 - busy
e7069000: 28000 - busy
e7091000: 170000 - free
e7201000: 101ff000 - free
Comments
- Anonymous
June 02, 2009
PingBack from http://patiochairsite.info/story.php?id=29472