10.16(화) 이론-1 ( 스택, 힙, DLL)

from Study/System 2007/10/16 16:49 view 28682
1. 스택의 원리
사용자 삽입 이미지


- Page-Guard : 접근시 예외를 발생시키는 속성을 가진다.

- 2번째 페이지 에 접근하면 Page-Guard는 Commit 이 되고 3번째 페이지가 Page-Guard 상태가 된다.

- 마지막 페이지에 도달하면 Reserve 상태가 된다. 이를 벗어 나면 오버플로우 가 발생한다.

- 메모리가 필요할 때 Commit 상태가 되는것이다.

- 메모리의 상태를 알고 싶다면 VirtualQuery, VirtualQueryEx를 쓴다.



char* addr = (char*)0x0;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery( addr, &mbi, sizeof(mbi) );

2. Heap
사용자 삽입 이미지

- 힙은 프로세스당 1개씩 있지만 새롭게 힙공간을 만들어도 된다.
- HeapAlloc, HeapFree 는 기본힙을 생성하고 소멸 해준다.
  1) 확보된 영역을 조금씩 쓰기 위해선 OS가 관리해주는 Heap메모리는
 Heap매니저가 담당해준다.( 소형 메모리 할당 )

  2) 좌측 그림처럼 메모리가 조각화 되어서 메모리 낭비가 발생한다.


- HeapCreate, HeapDestroy 는 새롭게 힙공간을 만들어 준다.
  1) 메모리 조각화 현상을 막을 수 있다. 새로운 힙공간에는 똑같은 크기의 메모리만 써서 메모리 낭비를 막는다.

2) 기본힙은 내부적으로 동기화를 수행하므로 멀티스레드에는 안전하지만 수행속도가 그만큼 느려진다. 단일 스레드 프로그램에선 힙을 하나 생성해서 동기화를 수행치 않게 되면 빨라진다.

사용자 삽입 이미지

- 윈도우즈 환경에서의 메모리 관리 함수들의 계층은 위 그림과 같다.
- 이외에도 GlobalAlloc ( 전역 힙 ), LocalAlloc ( 지역 힙 ) 이 있지만 이는 16bit시절에만 의미가 있고
- 지금은 HeapAlloc 이나 다름이 없다. 하지만 GlobalAlloc 은 유일하게 클립보드에 써줘야 한다.
The global functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE, the clipboard functions, and OLE data objects.


3. DLL

  - 프로세스에 로드될때 ( DllMain() 생성,초기를 해준다. )    DLL_PROCESS_ATTACH
  - 프로세스에서 해지될때 ( DllMain() 소멸자 역할을 한다. ) DLL_PROCESS_DETACH
  - 스레드가 생성시 ( DllMain() TLS공간을 만들어 준다. )     DLL_THREAD_ATTACH
  - 스레드가 파괴시 ( DllMain() TLS공간을 없애준다. )         DLL_THREAD_DETACH

   - DllMain은 Serialize 가 된다. 스레드 두개가 동시에 접근 못하도록 구현되어 있다.( 한스레드만 접근 )
BOOL WINAPI DllMain( HANDLE hDll,    // DLL 핸들, 결국 주소
                     DWORD  r,                    // DllMain 이 호출된 이유
                     LPVOID how                 // DLL이 Load된 방식( 0이면 LoadLibrary 사용 )
                    )

  - 동적TLS( 스레드에서 dll을 로드 했을 때 전역변수 문제를 해결한다. strtok 의 static변수 )
사용자 삽입 이미지
  - 멀티스레드 환경을 고려할 때 dll의 전역변수는 동적 TLS를 사용해야 한다.
  - 동적TLS는 사용하지 않는 Index에 메모리를 할당하는 기법으로 모든 스레드는 인덱스를 가지고 메모리에 접근한다. 이때 Index는 프로세스에 할당되어 있다.~
DWORD index = 0; // 동적 TLS index로 사용.
//////////////////////////////////////////////////////////////////////////////////

index = TlsAlloc();    // 동적 TLS에 빈슬롯 할당
buf = (char*)HeapAlloc( GetProcessHeap(), 0, 1000 );
// 주소를 TLS에 보관
TlsSetValue( index, (void*)buf );

TlsFree( index );
////////////////////////////////////////////////////////////////////////////////
// 새로운 스레드가 생성 될 때마다 메모리를 할당해서 Thread-Safe를 보장!!
buf = (char*)HeapAlloc( GetProcessHeap(), 0, 1000 );
TlsSetValue( index, (void*)buf );

buf = (char*) TlsGetValue( index );
HeapFree( GetProcessHeap(), 0, buf );
/////////////////////////////////////////////////////////////////////////////////


2007/10/16 - [Study/System] - 10.16(화) 실습 ( 스택,힙, 훅, DLL )
동적TLS MS문서
Tag | ,

Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다