[DDK] Lookaside List 란?

내가 왜 Lookaside List를 찾고 공부하고 있는 지는 모르겠지만,,

스케쥴표에 할일을 보니, Lookaside List 공부? 라는게 적혀있었다.

 흐음, 그제나 저제나 한번 알아볼까나,

  일단 Zone 영역을 알아보자, Zone 영역은 Windows NT 3.51 이전 버전에서 고정된 크기의

메모리 할당과 해제를 효율적으로 관리하기 위해서 Windows NT 실행부가 지원하는 구조체

이다.

 요약하면, Lookaside List나 Zone 영역은 Microsoft가 메모리 관리의 효율성을 위해서

만들어놓은 개념
이다.

이렇게 하고 Lookaside List로 들어가보자.

 Heap manager가 Heap을 관리한다. Heap은 동적으로 메모리를 사용할 수 있게 해준다.

예를 들면 이런 경우이다.
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.  
  4. int main(void)  
  5. {  
  6.     ...  
  7.  
  8.     char* p;  
  9.  
  10.     p = (char*) malloc( sizeof( char ) * USER_DEFINE_SIZE );  
  11.  
  12.     ...  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>#include <stdio.h> #include <stdlib.h> int main(void) { ... char* p; p = (char*) malloc( sizeof( char ) * USER_DEFINE_SIZE ); ... </TEXTAREA>

 이 코드를 보면 malloc()에 의해서 Heap 영역의 메모리가 할당되고 있다.

 이개념이야 뭐 프로그래머라면 다 알 수 있는 개념이다.

 그렇게 되면 이런 경우를 보자.

  연속하고 인접한 메모리가 존재하는데, 자신의 할당된 블럭 양옆이 할당이 되지 않은 채

존재하고 있다. 그리고 할당된 영역은 이제 곧 Free() 작업에 들어간다.

 그렇게 되면 Linear하게 쭈욱 메모리가 비어있게 된다.

 그렇게 되면 이 영역을 하나의 큰 블럭으로 합칠 수 있다.

항상 고정된 크기의 메모리 블럭만을 사용한다면 Heap을 관리하는 데 있어 훨씬

효율적인 방식을 사용할 수 있다.

 시스템은 실제 사용에 따라 모든 Lookaside List의 Depth를 정기적으로 조절한다.

이해하기 쉽게 예를 들면 C#의 가비지 컬렉터의 generation이랑 흡사하다.

 최저값은 4이고, 총 시간에서 5%이상 접근하지 않은 리스트의 depth를 감소시킨다.

 하나의 큰 수영장을 지어 놓고, (pool) 거기서 바가지로 물을 떠주는 것이다.

 흠 비유가 적절한가,, ; 메모리 풀(Memory Pool) 인것이다.

 하지만 수영장을 너무 크게 지어버리면 돈낭비이고 너무 작게 지어버리면 퍼줄 물도 없어서

오늘내일 할 것이다. 그렇지, ㅎ

 예전 버전에서는 이 바가지의 크기를 지정할 수도있었는데, 이제는 악덕한 주인이

바가지의 크기를 자기가 멋대로 정한다. ( 너무 악랄하게 안정하고 유도리 있게 정한다. )

 이제 바가지를 할당한다. 그리고 바가지에서 물을 빼간다. 다시 반환하면 바가지에 다시

물을 부어 넣는다. 넘치면? 수영장에 반환한다.

 모자라면? 수영장에서 퍼온다.

 간단하지 않은가? 이런 것은 누구나 생각해 낼 수 있지만, 먼저 생각못하면 젠장이다.

 예를 들면 버블 정렬( Bubble Sort ) 쫙다 비교하는거 누가 상상 못하겠는가,, -  _-

 
  1. PPAGED_LOOKASIDE_LIST pagedlist;  
  2. PNPAGED_LOOKASIDE_LIST nonpagedlist;  
  3.  
  4. ExInitializePagedLookasideList( pagedlist, Allocate, Free, 0, blocksize, tag, 0 );  
  5. ExInitializeNPagedLookasideList( nonpagedlist, Allocate, Free, 0, blocksize, tag, 0 );  
  6.  
  7. ...  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>PPAGED_LOOKASIDE_LIST pagedlist; PNPAGED_LOOKASIDE_LIST nonpagedlist; ExInitializePagedLookasideList( pagedlist, Allocate, Free, 0, blocksize, tag, 0 ); ExInitializeNPagedLookasideList( nonpagedlist, Allocate, Free, 0, blocksize, tag, 0 ); ... </TEXTAREA>

 인자에 대한 설명은 MSDN이나 DDK 문서를 참고하자,

 이제 이 수영장에서 물을 가져가는 일은 이렇게 한다.

 
  1. ...  
  2.  
  3. PVOID p = ExAllocateFromPagedLookasideList( pagedlist );  
  4. PVOID q = ExAllocateFromNPagedLookasideList( nonpagedlist );  
  5.  
  6. ...  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>... PVOID p = ExAllocateFromPagedLookasideList( pagedlist ); PVOID q = ExAllocateFromNPagedLookasideList( nonpagedlist ); ... </TEXTAREA>

이제 물을 바가지로 다시 반환하자.

  1. ...  
  2.  
  3. ExFreeToPagedLookasideList( pagedlist, p );  
  4. ExFreeToNPagedLookasideList( nonpagedlist, q );  
  5.  
  6. ...  

<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>... ExFreeToPagedLookasideList( pagedlist, p ); ExFreeToNPagedLookasideList( nonpagedlist, q ); ... </TEXTAREA>

※ 리스트 객체가 범위(scope)를 벗어나기 전에 lookaside list를 명시적으로 삭제하는 것은

매우 중요한 문제이다. lookaside list 객체를 DEVICE_EXTENSION에 넣고 난 후 IoDeleteDevice()

를 하기 전에 객체를 삭제 하는 것을 잊어 버리는 것
은 충분히 일어날 수 있는 실수이다.

 보통 프로그램을 짜다보면, Free를 안해줘서 메모리 릭이 생기는 경우가 발생한다.

 그 경우와는 차원이 다르다. 그건 메모리가 빵꾸나고 말지만, 여기서는 시스템이 Depth를 조정하기 위해

lookasideList를 참조할때, 이상한 메모리를 읽어 들여서 아마도 BSOD에 걸린다.

위로 스크롤