Upload
youngkwon-lee
View
1.713
Download
7
Embed Size (px)
DESCRIPTION
15장.애플리케이션에서가상 메모리 사용 방법16장.스레드 스택
Citation preview
Windowsvia
C/C++15 장 .애플리케이션에서가상 메모리 사용 방법
16 장 .스레드 스택
아꿈사2012-02-11
15 장 . 애플리케이션에서 가상 메모리 사용 방법
가상 메모리 관리 함수들의 사용법을 알아봅니다 .
가상 메모리 함수들을 사용하면• 주소 공간 내에 직접적으로 영역을 예약• 예약된 영역에 물리적 저장소를 커밋• 필요한 보호 특성을 설정
1. 주소 공간 내에 영역 예약하기LPVOID 예약된 메모리 주소VirtualAlloc( 가상 메모리를 예약하는 함수 LPVOID lpAddress, 예약하고자 하는 메모리 주소 SIZE_T dwSize, 영역의 크기 DWORD flAllocationType, 예약할 것인지 커밋할 것인지 DWORD flProtect 보호 특성 );
가상 메모리를 예약하는 함수
LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
대부분의 경우 NULL 값을 전달 .시스템이 프리 주소 영역 중 가장 적절한 공간을 찾아낸다 .
주소를 지정할 때에는꼭 프로세스의 유저 모드 파티션을 가리키는 값을 전달해야 한다 .
주소는 할당 단위어야 한다 .(13 장 sec3 참조 )
LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
시스템은 항 상 CPU 의 페이지 크기의 배수로 영역을 예약
4KB, 8KB, 16KB 페이지 크기를 사용하는 머신에서62KB 를 예약하려 하면64KB 로 예약한다 .
LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
MEM_RESERVE: • 영역 예약MEM_TOP_DOWN:• 단편화를 피하기 위해 높은 주소 공간
상에 영역을 예약하기 원할 때 .
다른 값들은 나중에 살펴봅니다 .
LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
13 장 section6 보호특성을 참조 . P501
PAGE_NOACCESSPAGE_READONLYPAGE_READWRITE…
LPVOIDVirtualAllocExNuma( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, DWORD dwPreferredNumaN-ode );
NUMA(Non-Uniform Memory Access)
머신에서 수행되는 경우 성능 개선을 위해 특정 노드에 탑재된 램으로부터 가상 메모리를 확보할 때 사용한다 .
참조14.3 NUMA 머신에서의 메모리 관리
2. 예약 영역에 저장소 커밋하기메모리에 접근하기 위해 커밋이 필요함 .커밋은 페이지 크기 단위로 수행된다 .
커밋할당된 물리적 저장소에메모리 영역을 매핑하는 것 .
13 장 section4 물리적 저장소를 영역으로 커밋하기 . p496
커밋 방법LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
MEM_RESERVE 대신MEM_COMMIT 을 사용한다 .
dwSize 전달하여 전체를 커밋하지 않을 수 있다 .
3. 영역에 대한 예약과 저장소 커밋을동시에 수행하는 방법
LPVOIDVirtualAlloc( LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );
MEM_RESERVE 와MEM_COMMIT 을 동시에 사용한다 .
큰 페이지 단위 (Laarge-Page Granularity) 를 사용하게 되면 성능을 개선할 수 있다 .
‘ 큰 페이지’의 최소 크기를 얻어오는 함수GetLargePageMinimum
VirtualAlloc 을 호출할 때MEM_LARGE_PAGE 플래그를 사용 .
MEM_LARGE_PAGE 를사용하면 메모리 공간을 페이징 불가능 영역으로 설정하여 항상 렘에 유지된다 .성능↑
4. 언제 물리적 저장소를 커밋하는가
가상 메모리 기법의 유일한 문제점은언제 물리적 저장소를커밋할지 판단해야 한다는 것 .
커밋되었는지 확인하는 방법1. 항상 커밋해 본다 .– 가장 쉽지만 느려진다 .
2. VirtualQuery 로 확인한다 .– 1 번보다 느리다 .
3. 페이지 커밋 여부를 따로 기록한다 .– 복잡한 작업이 될 수 있다 .
4. 구조적 예외 처리 (SEH) 를 사용한다 .• 코드가 적고• 가장 빠르다 .
SEH 는 23, 24, 25 장에서 자세히 다뤄진다 .
5. 물리적 저장소의디커밋과 영역 해제하기
BOOLVirtualFree( LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType );
해제할 때 MEM_RELEASE 를 사용 .
해제 시에는lpAddress 는 시작 주소dwSize 는 0 이어야 한다 .
예약했던 영역을 한번에 해제해야 함 .
BOOLVirtualFree( LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType );
디커밋할 때 MEM_DECOMMIT 을 사용 .
페이지 단위로 가능
lpAddress 시작주소 , dwSize 0 이면전체를 디커밋 .
lpAddress + dwSize 가 페이지 중간쯤이면lpAdress ~ lpAdress + dwSize 까지모든 페이지 디커밋
6. 보호 특성 변경하기VirtualProtect 로 변경 가능 .
잘 활용하면 잠재적인 버그로부터 보호할 수 있다 .
예 ) 메모리를 사용할 때만 PAGE_READWRITE사용하지 않을 때 PAGE_NOACCESS 로 변경해서접근 위반 에러를 발생하게 하는 것 .
7. 물리적 저장소의 내용 리셋하기물리적 저장소 리셋 :N 개의 페이지 내용이 수정되지 않았다고 시스템에게 알려주는 것 .수행 성능을 향상 시킨다 .
예 ) 페이지를 로드할 때
1 2 3
1 2 3 4 5
1. 2 를 저장 2. 4 를 로드
물리적 저장소가 꽉 차있고 4 번 페이지를 사용할 경우 .
1 4 3
예 ) 리셋을 사용하면
1 2 3
1 2 3 4 5
1. 바로 4 를 로드
시스템은 2 번이 수정되지 않았다고 알기 때문에 2 를 저장 안함 .
1 4 3
성능 향상 !
주의 !
할당할 때 리셋할 때
시작주소 내림 올림
할당크기 올림 내림
위와 같이 다른 이유는 실수로 페이지를 리셋해 버리는 것을 막기 위함 .
또한 MEM_RESET 은 항상 단독으로 사용되어야 한다 .
MemReset 예제 실행하지 말자 . 컴퓨터 왕 느려짐 .
주소 윈도우 확장• AWE (Address Windowing Extension)• 32 비트 윈도우에서 더 많은 메모리를
사용하기 위한 방법 .
AWE 특징• 디스크로 스왑되지 않는다 .• 주소 공간보다 더 큰 램에 접근할 수 있다 .• 프로세스 주소 공간에 보여지지 않는다 .• 주소 윈도우 (Address Window) 를 통해
접근한다 .–코드양이 많아진다 .
주의• SQL Server 2012 부터 AWE 를 지원 안함 .• http://msdn.microsoft.com/ko-kr/libra
ry/ms143179(v=sql.110).aspx
16 장 . 스레드 스택• 시스템에서 직접 주소 공간을 예약한다 .• 스레드 생성시 스택 메모리 공간–기본적으로 1MB 의 주소 공간을 예약–두 개의 페이지만 커밋
• 스택 영역은 모두 PAGE_READWRITE 특성
스레드 스택의 페이지 상태메모리 주소 페이지 상태
0x080FF000
커밋된 페이지 ( 최상위 )
0x080FE000
커밋된 페이지 ( 가드 특성 )
0x080FD000
예약된 페이지
…
0x08000000
예약된 페이지 ( 최하위 )가드 페이지에 접근하면 현재 가드페이지를 해제다음 페이지를 가드페이지로 지정 .
모두 사용하였을 경우메모리 주소 페이지 상태
0x080FF000
커밋된 페이지 ( 최상위 )
0x080FE000
커밋된 페이지
…
0x08001000
커밋된 페이지
0x08000000
예약된 페이지 ( 최하위 )최하위 영역은 항상 예약 상태로만 두고 커밋하지 않는다 .
0x08001000 에 물리적 저장소를 커밋할 때EXCEPTION_STACK_OVERFLOW 예외를 발생시킨다 .
최하위 페이지를 예약 상태로만 유지하는 이유
메모리 주소 페이지 상태0x080FF00
0커밋된 페이지 ( 최상위 )
0x080FE000
커밋된 페이지
…
0x08001000
커밋된 페이지
0x08000000
예약된 페이지 ( 최하위 )
0x07FFF000
다른 용도로 커밋된 페이지0x08001000 영역을 다 사용하고 0x08000000 을 사용하면 접근 위반이 발생 .최하위 영역을 커밋한다면 0x07FFF000 에 접근할 수 있다 .
스택 크기 변경 방법• IDE 에서 변경– VC++ 컴파일러 /F 옵션–링커 /STACK 옵션
• 코드에서 변경– CreateThread, _beginthreadex 호출 시
지정
1. C/C++ 런타임 라이브러리의 스택 확인 함수
스택을 주소 공간에 할당하더라도사용 전까지는 물리적 저장소에커밋하지 않는다 .
스택 확인 함수오른쪽 함수는4KB 페이지 크기 시스템에서4 개의 페이지가 필요함
스택은 2 개만 커밋되어 있음
스택을 확인하는 함수가 필요 .
void SomFunction(){ int nValue[4000]; // 16,000바이트 nValue[0] = 0; // 할당 작업 수행}
• 스택 확인 함수는 사용되는 영역이 커밋되었는지 확인 .
• 컴파일러는 스택 확인이 필요한 곳에 자동적으로 스택 확인 함수 호출 코드를 포함 .
1. Summation 예제 애플리케이션
StackOverFlow 발생시 SHE 를 사용하여 우아하게 종료한다 .
감사합니다 .