메모리 단편화

메모리 단편화

2019년 7월 9일 프로그래밍 0

오늘은 어플리케이션 메모리 단편화에 대해 이야기해보고자 합니다.

일단 일반적인 개발방법으로 개발을 진행했다면 메모리 단편화는 반드시 일어납니다.
고가용성 프로그램 개발을 목적으로 설계단부터 메모리 관리 방식을 별도로 고려하지 않았다면, 정도의 차이일 뿐 메모리단편화는 필연적으로 발생하는 것이죠.

물론 해결을 위한 여러가지 기법들이 우리도 모르는 사이에 여러 레이어에 걸쳐 적용되어 있습니다.

1. 메모리 할당 함수 내부에서의 최적화
대부분의 메모리 할당 함수(C/C++ malloc, new 등)에는 기본적으로 메모리 파편화를 방지해주는 알고리즘이 포함되어 있습니다.
자세한 내용은 조금 다를 수 있겠지만, 큰 개념으로 보면 링크드리스트형태로 메모리할당 관련 정보를 내부적으로 관리하며 요청된 메모리할당 크기에 맞는 메모리 영역을 찾아 재사용하는 형태로 구현되어있습니다.

2. 운영체제 제공 LFH
운영체제 단에서 작은 크기의 메모리를 반복적으로 할당/해제 시 발생하는 메모리단편화를 방지하기 위해 내부적으로 메모리를 관리하며 메모리 영역을 재사용하게합니다.
프로세스에 실제 메모리 할당/해제를 반복해보면, 메모리를 보면 일정 크기의 블록으로 나누어 자동적으로 관리하는 것을 확인 할 수 있습니다.(그래서 메모리 할당/해제 요청 시점에 즉시 메모리 주소공간에 해당 내용이 적용되지 않습니다. 메모리 해제를 하더라도 실제 메모리 주소공간에서 제거되지 않습니다.)

위 2가지 방법을 통해 자동적으로 메모리 단편화가 일어나지 않도록 내부적으로 관리되고 있기 때문에, 통상적인 환경에서는 메모리 단편화가 문제되는 경우는 거의 없다고 보시면 됩니다.

문제는 “통상적인 환경”이 아닌 연단위의 고가용성을 요구할 때 발생하게 되죠.
이 문제를 해결하는 방법은 크게 두가지가 있습니다.

1. 자체 메모리 풀 구현
개발할 때 사용하는 각종 풀과 같은 개념의 메모리 풀을 구현하는 방법입니다.
필요한 메모리(객체)들을 미리 생성해놓고 사용할때마다 풀에서 가져와서 사용하는 방법입니다.
애초에 할당/해제를 반복하지 않도록 설계를 하는 것이지요.
물론 메모리 할당 단위가 단순 버퍼 블록인지, 객체인지 여부에 따라 설계 방식에 많은 차이가 발생하게 됩니다.

2. Private Heap 사용
디폴트 힙을 사용하지 않고, 별도의 세그먼트 힙을 생성하여 사용하는 방식입니다.
일정 루틴이 시작되면 별도의 힙 영역을 생성하여 사용하고, 루틴이 끝나면 힙 영역 “자체”를 제거하여 메모리 할당흔적 자체를 지워버리는 방식입니다.
디폴트 힙과 세그먼트 자체가 다르기 때문에, 말그대로 메모리 할당 흔적조차 없이 완전히 제거됩니다.
디폴트 힙 외에는 메모리 할당/해제 요청에 대해 스레드 동기화를 하지 않기 때문에, 잘만 사용한다면 성능상의 이점도 존재하게 됩니다.

위 두가지 방법은 굉장히 높은 수준의 고가용성을 요구하는게 아니라면, 오버엔지니어링이 될 수 있습니다.
그리고 소프트웨어 설계단부터 고가용성을 요구한다면, 대부분 하드웨어 역시 고가용성을 지원하는 하드웨어를 요구하는 경우가 많습니다.(ECC 메모리 지원 등)

정부 과제등의 이유로 고가용성 프로그램이 반드시 필요한 상황이 아니라면, 개인적으로는 통상적인 개발 방법 + 주기적인 서버 재부팅 등도 좋은 방법중에 하나라고 생각하고 있습니다.





답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다