
메모리 구조는 프로그래밍에서 매우 중요하다. 이걸 몰라도 코드를 짜는것은 가능하지만 더 나아가 코드를 잘 짜기 위해서는 무조건 알아야 하는 개념이다.
컴퓨터의 주기억장치는 메모리 즉, 램이라는 사실은 전공자라면 알고있을 것이다. 램에는 변수, 함수, 코드 등등 다양한 정보들이 저장되는 공간이기 때문에 매우 중요하다.
메모리는 이렇게 구조가 되어있다.
우리가 코드를 입력하면 컴퓨터가 바로 알아들을 수 있을까? 당연하지만 정답은 X이다. 컴퓨터는 0과 1로 이루어진 2진 기계어만 알아듣기 때문에 우리가 코드를 통해 명령을 하면 중간에서 번역하는 과정을 거치게 된다.
코드 영역에는 코드 글자 즉, 스크립트가 저장된다고 생각하면 된다.
데이터 영역에는 정적변수와 전역변수가 저장되는 공간이다. 즉, 우리가 사용하는 "Public" 혹은 "Static"과 같이 한번 선언이 되면 프로그램이 끝날때 까지 없어지지 않고 남아있게 된다. 즉, 필요이상으로 많이 사용하게 되면 메모리 낭비가 바로 이뤄지는 것이다.
스택은 지역변수나 매개변수를 저장한다. 저장한 정보들은 코드 블록이 끝나면 지워지게 된다. 그렇기 때문에 우리가 지역변수를 사용하면 다른 코드블록에서 사용할 수 없는 이유가 여기에 있는 것이다.
코드 블록 안에 있는 "값 타입"의 변수들은 함수의 호출이 끝나면 스택에 할당된 메모리는 자동으로 해제된다.
클래스는 참조 타입이다.
우리가 새로운 객체를 만든다면, 그 객체를 직접적으로 가지고 있는 것이 아니라, 주소를 통해 그 객체를 가르키는 개념이다.
public class Test{
//
}
void start(){
Test test1 = new Test();
Test test2 = new Test();
}
이렇게 생성한다면 test1에는 Test 객체가 저장이 되어있는 것이 아니라, 생성된 Test객체를 참조할 수 있는 주소값을 test1이 가지고 있는 것이다.
이 설명을 다시 한 이유는 힙과 스택에 관련이 있기 때문이다. 이렇게 만들어진 객체, 즉 Test 객체들은 "힙" 영역에 저장이 되고, 이 주소를 가지고있는 test1,test2는 "스택" 영역에 저장이 된다.
그러면 여기서 중요한 점이 있다. 스택은 함수의 호출이 끝나면 해제되는 영역이기 때문에 위와같이 new를 통해 객체를 만들면 그 객체를 참조하던 stack즉 test1, test2는 지워진다. 하지만 생성되었던 객체들은 heap영역에 남아있게 되면서 메모리를 차지하게 된다.
그렇기 때문에!! C, C++, C#에서는 프로그래머가 힙 영역을 해제해야 메모리를 비워줘야 한다. 하지만 다행히도 C와 C++에 비해 비교적 최근에 나온 C#은 가비지 콜랙터가 있기 때문에 사용이 끝난 힙 데이터는 알아서 지워준다. 따라서 신경은 조금은 덜 써도 괜찮다.
하지만 가비지 콜랙터가 힙 메모리를 비울때 치명적인 약점이 있다. 바로 모든 수행을 멈추고 비운다는 것이다. 따라서 아무생각없이 힙 영역의 메모리를 가득채워버리면 가비지 콜랙터가 힙을 비우는 사이에 유저는 소위 말하는 렉이나 프레임 드랍을 경험하게 되는것이다.
+) 추가적으로 우리가 int a = 5라고 한다면 a와 5가 모두 스택영역에 저장이 되어 관리가 되지만, object a = 5라고 한다면, object는 참조형이기 때문에 5라는 값은 힙 영역에 저장이 되고 스택에는 5를 가르키는 주소를 가진 a라는 object가 저장이 된다. 이를 "Boxing" 이라고 한다.
그렇다면
object a = 5 //boxing
int b = (int)a; // unboxing
이렇게 b에 a가 참조하는 값을 넣어줄 경우, 힙 영역 데이터를 스택 영역에 할당하게 된다. 이를 "UnBoxing" 이라고 한다. 하지만 5라는 값은 힙영역에서 그대로 가져온 것이 아니라 복사해서 스택 영역에 넣은것이기 때문에 힙 영역에는 그래도 데이터가 남아있고, 이는 가비지가 된다.
딱봐도 그냥 자료형을 사용하는것 보다 참조형인 object를 사용하면 가비지가 더 생성되기 때문에 사실 사용을 기피한다. (공식문서에서도 자주 사용하지 말것을 강조하고 있다.)
게이머 TV
지영7130's history(메모리 구조와 유니티)
본 포스팅은 개인 학습용으로 상업적 목적을 포함하지 않습니다.