C언어와 C++에서는 new 연산자와 malloc 함수를 이용해서 힙(heap)영역에 동적 메모리 할당을 받고 delete 연산자와 free 함수를 이용해서 동적 메모리를 해제하게 된다.


heap 영역에 메모리를 할당하게 되면 자유메모리 블록 리스트(Free memory block list)로 관리가 된다.


새로운 메모리를 할당 할 때에는 자유메모리 블록 리스트를 참고하여 필요한 만큼의 메모리를 할당 할 수 있는 공간을 찾는다.


찾으면 자유 메모리 블록 리스트에 추가하고 할당한 해당 메모리 공간을 초기화 시킨다.


아래 그림을 보면 쉽게 이해가 될 것이다.



처음 malloc(7000); 으로 7000바이트에 메모리를 할당받는다.

가장 첫번째 A영이있는 앞부분부터 탐색을 시작하여 사용하지 않는 메모리를 찾습는다.

B구역이 사용하지 않는 메모리이지만 크기가 4k밖에 안되게 때문에 계속탐색을 하여 가장 뒷부분인 E영역에 할당을 하게 된다


그리고 free(C) 로 C블록을 메모리를 해제시킵니다. 그러면 C영역에 5000바이트의 메모리가 해제가 된다..

이때 malloc(5000) 으로 메모리를 다시 할당하게 된다.

A부터 해서 다시 빈메모리영역을 찾습니다. G영역이 9k가 비어있기 때문에 앞쪽부터 5000바이트에 메모리를 할당 한다.


이런방식으로 계속 메모리 할당과 해제를 계속 하다보면 메모리 단편화가 일어날 수 있다.

메모리를 할당과 해제를 계속하다보면 중간중간 사용하는 메모리와 사용하지 않는 메모리가 존재하게 되된다. 

아래그림처럼 사용하는 메모리와 사용하지 않는 메모리가 있는데 여기서 300바이트가 넘는 메모리를 할당요청하게 되면 할당이 실패하게 된다. 전체 사용하지 않는 메모리는 850바이트나 되지만 단편화가 일어나서 메모리 할당에 실패하게 된다.



메모리 단편화를 피하려면 메모리를 너무 자주 할당 해제하는 것을 피하는 것이 좋다.


그리고 이와 같은 메모리 할당 방식은 앞에서 부터 빈 메모리영역을 탐색하기 때문에  Heap 메모리 영역을 탐색하는데 많은 시간이 소요될 수 있다. 특히 메모리 크기가 크고 빈 메모리영역이 뒷쪽에 있다면 매번 메모리 할당에 오버헤드가 발생한다.


그리고 할당만 하고 해제를 하지 않으면 메모리가 낭비될 수 있다.


사용자가 직접 해제를 시켜줘야하기 때문에 많은 주의가 필요하다.


이런 사용자가 직접 메모리를 할당하고 해제하는 방식과 반대로 가비지 컬렉터가 사용하지 않는 메모리를 자동으로 해제하는 방식에 가비지 컬렉션이라는 방식이 존재한다.

C++ 이후에 등장한 대부분에 언어에서는 이런 가비지 컬렉션을 사용한다. 예를들면 JAVA, C#, GO 언어 들이 가비지 컬렉션을 사용한다.


C#/.NET 가비지 컬렉션의 메모리 할당 및 해제 기본 원리 : http://hijuworld.tistory.com/32


Posted by 꿈만은공돌
,