Programming/Win32 API2008. 11. 19. 11:16
Question
  Win32 API 책(30장메모리 부분)을 보니까 메모리 할당 부분에 malloc와 new가 나오고
가상 메모리 부분에 VirtualAlloc이 나오든데
그럼 malloc하는 부분은 가상 메모리가 아니란 말씀이신가요?
malloc 하는 부분과 VirtualAlloc 하는 부분의 메모리가 다른 부분인가요?

그리고 그 뒤에 힙 부분에 HeapAlloc와 GlobalAlloc, LocalAlloc 가 나오든데
HeapAlloc는 Win32함수이고 다른 두 개는 Win16의 잔재라고 나와 있더군요.
그래서 이 차이점은 알겠는데
제가 듣기론 malloc도 힙 영역에 메모리를 할당한다고 들었는데
그런것 아닙니까? malloc는 힙 아닌 다른 영역에 할당 하나요?
힙 부분에 다른 함수들이 나오니까 다른 영역에 할당 하나 싶어서요.
그리고 HeapAlloc나 GlobalAlloc는 가상 메모리에 할당 하는게 아닌가요?
가상 메모리의 힙 영역에 할당하는 것인가요?

일단 제가 이해 하기로는 모두 실질적인 메모리에 할당 하는 것은 아니고
가상 메모리에 할당하고 이것을 페이징 해서 실제 메모리에 올리고 사용하고
내리고 하는 걸로 알고 있는데 맞나요?
그리고 가상 메모리의 VirtualAlloc가 할당하는 부분과 malloc가 할당하는 영역,
그리고 HeapAlloc가 할당 하는 영역은 다르다.
이런 건가요?
Answer
  가상메모리란 말그대로 실제 메모리가 아닌 가상의 메모리입니다. win32 환경에서
모든 프로세스는 독립적인 4G 공간의 메모리 주소 공간을 가지게 됩니다. 그런데
실제로 4G의 메모리를 탑재하고 있는 컴퓨터는 없으며, 4G * 프로세스의 갯수
만큼의 메모리를 탑재한 컴퓨터는 더더욱 없습니다. 따라서 없는 것을 실제로
눈에 보이는 것처럼 만들기 위해서 몇가지 트릭이 사용됩니다. 가장 큰 트릭이
스와핑과 페이징이죠.

스와핑은 현재 실제 사용중이지 않은 메모리를 디스크로 옮기고, 실제로 필요한
페이지가 없을 경우 디스크로 부터 로딩해서 사용하는 기술입니다. 페이징은 좀
더 복잡한 개념인데, 가상 메모리가 실제 어떠한 물리 메모리로 맵핑 되는지의
정보를 가지고 있고 그것들을 변환하는 기술이라고 보시면 됩니다.

이것과 별개로 힙메모리라는 것이 나오는데, 이것은 프로세스에서 빈번히
사용하는 서로다른 크기의 작은 메모리 할당/해제시의 단편화가 적고 빠르게
되도록 만든 구조의 메모리 입니다. 이러한 메모리가 별도로 존재하는 것은
아니고 소프트웨어적으로 그렇게 관리하는 것을 말합니다. 보통은 특정한 크기의
풀을 만들어 두고 해당 풀의 메모리를 효율적으로 분할해서 쓰는 방식을 많이
사용합니다.

그럼 각각 이것들을 조작하는 API를 살펴보도록 하죠. 가장 저수준의
VirtualAlloc이라는 함수는 실제 가상 메모리를 할당받고 해제하는 함수입니다.
VirtualAlloc함수를 통해서는 실제 메모리 할당 뿐만 아니라 해당 페이지를
예약하는 등의 저수준 제어도 할 수 있습니다.

HeapAlloc이라는 함수는 힙에 메모리를 할당하는 함수입니다. HeapAlloc의 첫번째
인자로 넘어가는 것이 힙 핸들이죠. 힙은 HeapCreate함수를 통해 생성할 수
있으며, win32에서는 프로세스별로 하나의 기본 힙이 제공됩니다.
GetProcessHeap을 통해서 구할 수 있습니다.

malloc, free, new, delete 함수는 위의 API 보다 좀 더 상위의 계층에서 이러한
일들을 하게 됩니다. C 런타임 라이브러리 초기화 코드에서 해당 라이브러리의 힙
관리자 들이 별도의 힙 메모리를 만들고 관리하게 됩니다.

단순하게 이해하기 위해서는 그냥 위의 세가지 종류가 계층 구조라고 생각하면
편합니다. VirtualAlloc이 가장 하부의 계층, 그것을 이용해 HeapAlloc등의 API가
구현되고, 그 상위에 CRT 힙 함수들이 존재하는 것이죠.

실제로 응용 프로그램 계층에서의 대부분의 작업은 CRT 함수로도 충분히
가능합니다. 별도의 자료 구조를 특정 힙에 할당하는 방법을 쓸때에 Heap함수들을
사용하나 그렇게 자주 있는 일도 아니죠. VirtualAlloc을 쓰는 일은 물론 더더욱
없겠죠. 실제로 대용량 메모리를 사용해야 하는 경우에도 Memory mapped file을
통해서 처리하는 것이 일반적입니다.

음... 쭈욱 적고 밑에 질문글을 다시 보니 동문서답한 느낌도 드네용... ㅋㅋㅋ~

결론적으로 말하면 메모리는 하나입니다. 컴퓨터 뜯어보면 하나죠. ㅋㅋ~ 당연히
프로그램에서 사용하는 메모리도 그거 하나입니다. 하지만 편의상 메모리를
나눠서 쓰겠죠. 우리가 용돈을 받았을때 이건 차비, 식비,... 등으로 쪼개
쓰는것과 같다고 보면 됩니다. 컴퓨터도 그런식으로 용도에 맞게 메모리를
효율적으로 사용하기 위해서 가상메모리, 힙, 스택메모리 같은걸로 분리해서
사용합니다~

--
신영진 (Shin, YoungJin)
http://www.jiniya.net


Posted by skensita