Posted in: 프로그래밍

메모리 Reallocation (재할당)

 메모리 재할당은 “필요한 메모리의 양이 바뀌어서 다시 메모리를 할당 받는것”이다. 코딩을 하다보면 메모리를 재할당 받아야 할 때가 종종 찾아온다. 사용자가 직접 메모리 재할당을 할 때도 있고, Python처럼 언어에서 보이지 않게 알아서 재할당을 진행할 때도 있다.

 위의 그림을 해석해 보자. 기존에는 데이터를 저장할 때 8Byte의 공간을 필요로 했으나, 어떤 사정에 의해 14Byte가 필요해 졌다. 그래서 메모리 re-allocation을 통해 총 14byte의 공간을 재할당 받았다. 덕분에 사용할 수 있는 메모리 공간이 늘어나서 원하는 데이터를 다 집어 넣을수 있게 되었다.

 실제 상황을 생각해 보자. 파이썬에서 빈번히 쓰이는 List를 들여다 보자. List는 저장되는 항목의 갯수에 따라서 메모리를 할당 받는다. 그러다가 할당 받은 메모리량 이상으로 항목을 저장해야 할 때 PyMem_Realloc을 통해 필요한 만큼 메모리를 재 할당 받는다.

 

 그림의 상황을 보자. 처음에는 4개의 항목만 저장할 수 있으면 충분했다. 그래서 4개 항목치의 메모리만 할당 받았다. 그런데 문제가 생겼다. 총 6개의 항목을 저장해야 할 일이 생긴것이다. 4개의 칸에 6개의 물건을 넣을수 없는것 처럼, 4개 항목만 저장 가능한 List에 6개의 항목을 저장할 수 는 없는 노릇이다. 어쩔 수 없이 메모리 재할당을 통해 새로 6개(Padding을 통해 총 8개)를 저장할 수 있는 공간을 확보했고, 덕분에 6개 항목을 모두 저장할 수 있었다.

하지만 위에 있는 예시들은 메모리 재할당이 매우 잘 이루어진 상황이다. 메모리 재 할당 과정시 데이터 뒷편에 메모리가 널널하면 위의 그림같이 뒤로 늘려만 주면 된다. 하지만 뒤에 충분한 메모리 공간이 없다면 늘려주는것은 불가능 해 진다. (이미 누군가 쓰고있는 메모리 공간을 침범할 수는 없으니까!)

 그러면 위의 그림같이 데이터 할당 영역을 아예 옮겨줘야 한다. 아무 생각 없이 늘리기만 하면 기존에 존재하는 다른 데이터가 손상돼 버린다. 기존에 잘 있던 데이터를 건들 수 는 없기에 메모리에 남아있는 다른 공간에서 필요한 만큼 새로 메모리를 할당 받아야 하는 것이다.

 메모리를 옮기려면 [필요한 만큼 메모리 할당 ▶ 기존에 있던 데이터들을 새로 할당한 곳에 복사 ▶ 기존 영역 정리]의 3가지 과정이 필요하다. 물론 이 작업 자체는 성능에 크게 영향 주지는 않는다. 하지만 쓸데없이 너무 빈번하게 재할당이 이루어진다면 프로그램의 성능엔 영향이 안갈래야 안갈수 없을 것이다.

 빈번한 메모리 재할당은 특히 문자열 관련 작업에서 쉽게 찾아볼 수 있다. StringBuilder같이 미리 메모리를 할당해서 작업하는 경우가 아니라면 문자열을 이어 붙일때 마다 새로 메모리를 할당 받아야 하는 것이다.  (물론 컴파일러 최적화가 있긴 하지만, 여기서는 논외로 한다)

a = "가나다" <- a는 "가나다" 저장에 필요한 3칸의 메모리만 가진다
b = "라마바" <- b는 "라마바" 저장에 필요한 3칸의 메모리만 가진다

a += b       <- a에 "가나다라마바"를 저장해야 하기에, 메모리를 기존 3칸에서 6칸으로 늘린다.

 메모리 재할당은 가급적 피할 수 있으면 피하는게 좋다. 위의 예 같은 메모리 재할당이 생각보다 우리 주변에 많이 있을 수 있는데, (특히 빈번하게 실행되는 부분이라면) 가능한 줄이도록 시도해 보자. 어쨋든 처음 한번만에 깔끔하게 메모리를 받아내는 것 보단 Cost가 꽤 나간다.

 번외로, Page단위의 재할당은 실제 데이터의 복사 보다 mremap을 통해 내부의 변수 값만 달라짐으로 더 빠를 순 있을것 같다.

댓글 남기기

이메일은 공개되지 않습니다.

댓글을 작성하기 위해 아래의 숫자를 입력해 주세요. *