냉장고 정리를 해본적이 있는가? 본인은 예전에 자취를 하면서, 꽉찬 냉장고를 정리한적이 있다. 냉장고 정리를 하고나니(버린것이 아닌 내용물들의 재배치만 하였다.) 꽉차보였던 냉장고에 여유공간이 생겼다.
냉장고 전체를 메모리라고 보고, 냉장고에 들어있는 내용물들을 메모리를 차지하는 데이터라고 생각해보자, 분명 더이상 들어갈 자리가 없는 냉장고인데 재배치를 하고나니 여유 공간이 생겼다. 이는 애초에 수치적인 공간이 부족했던게 아니라 일정크기의 내용물이 들어갈 연속된 공간이 없던것이다. 냉장고의 빈곳 일부 일부를 다 합치면 김치통 하나 더 들어갈 자리는 있지만, 각각의 부분에는 한번에 넣을수 없다는 말이다. 김치통을 여러 조각으로 분리하지 않는한 말이다.
단편화
단편화의 사전적 정의는 다음과 같다. “분열된 것” 이다. 메모리의 단편화라고 한다면 ‘메모리가 분열된 것’ 이라고 생각하면 된다. 위의 냉장고 이야기 처럼, 분명 절대적인 사용량은 충분하지만 질제로 사용할수 있는 공간이 없다는 것이다. 메모리의 빈공간에 존재해야할 데이터들이 여러 조각으로 나뉘어, 저장되는 현상이기 때문에 사용할수 있는 공간이 점차 사라진다. 발생하는 현상에따라 크게 두가지로 나뉜다. 외부/내부 단편화가 그것이다.
외부 단편화
[출처 : 나를위한노트, https://developer-mac.tistory.com/21]
외부단편화는 메모리 할당과 해제가 반복되면서 위 그림처럼 중간 중간 빈공간이 생긴다. 저렇게 빈공간을 다합치면 충분한 공간이 있지만, 한공간단 크기가 작아 메모리가 더이상 할당되지 못하는 현상이 외부단편화 이다.
가장처음에 이야기한 냉장고이야기가 이러한 현상이다.
내부 단편화
[출처 : 나를위한노트, https://developer-mac.tistory.com/21]
내부 단편화는 메모리가 할당될때 필요한(실제 사용될) 크기보다 더 크게 할당되어 생기는 현상이다. 패딩데이터를 생각하면 쉽겠다.
단편화 해결법
아래는 대표적인 단편화 해결법이다.
- 압축(Compaction) : 메모리를 재배치하여 분산되어있던 메모리공간을 하나로 합치는(압축하는) 해결법이다. 냉장고의 내용물들을 정리(재배치)하여 더 넣을 공간을 만든것이 이 방법이다.
- 통합(Coalecing) : 압축과 헷갈리기 쉽지만, 압축과 다르게 인접한것끼리 합치는(통합) 것이다. 하나의 메모리를 기준으로 근처에 있던것끼리 뭉쳐서 큰 메모리 덩어리로 만드는 것이다. 재배치가 일어나는 압축과는 다르다.
- 페이징(Paging) : 가상메모리(보조기억장치 이용)를 일정크기의 블록(페이지)으로 나누어 둔다. 주기억장치에서 이 페이지와 같은크기로(프레임) 나눈다. 사용하는 데이터는 프레임에, 사용하지 않는것은 페이지 옮겨서 단편화를 해결한다. 단 이는 외부 단편화만을 해결해준다.
- 세그멘테이션(Segmentaion) : 이또한 역시 가상메모리를 이용하며 페이징과 다르게 같은크기인 페이지가 아닌 서로 다른크기로 나눈다.(세그먼트) 이러한 세그먼트는 논리적 단위로 나뉘며, 논리주소로 물리메모리를 맵핑하여 사용하는 방식이다. 페이징과 다르게 내부 단편화만을 해결해준다.
- 메모리풀(Memory pool) : 미리 일정크기, 갯수의 메모리를 할당해놓고 필요할때마다 미리 할당된 메모리를 빌려주고 사용이 끝나면 풀에 반납하는 방식이다. 메모리 할당 / 해제 비용이 들지 않아 서버에서도 많이 쓴다고 한다. 유니티에서도 객체를 할당 / 해제하는것보다 오브젝트를 미리 생성해놓고 SetActive()로 활성화 / 비활성화 하는 방식인 오브젝트풀이 이와 같다.