프로그램이 프로세스가 되어 메모리에 로드되면 크게 코드영역과 데이터 영역으로 나뉩니다. 여기서 코드영역이라는 것은 컴파일 된 명령어의 집합이 차지하는 공간으로 프로그램이 실행된다는 것은 이 코드영역의 명령가 한 라인씩 수행되는 것을 의미 합니다.
데이터 영역은 다른 말로 상수 영역이나 정적 영역이라고 하는데, 주로 프로그램의 로드와 함께 메모리를 차지하게 되는 상수, 리터럴(literal), 정적(static) 변수, 글로벌 변수가 자리를 잡게 됩니다. 우리가 static 이나 글로벌 변수에 큰 메모리를 할당 하면 안되는 이유는 해당 영역은 프로그램의 로드와 함께 생성되는 영역이고, 프로그램이 언로드될 때, 즉 모든 수행이 끝나고 메모리에서 내려갈때까지 유지되는 영역이기 때문입니다.
코드 영역은 말 그대로 수행될 명령어가 놓여지는 영역입니다. 따라서 이 부분 역시 프로그램의 크기와 비례한다고 볼 수 있습니다. 코드 영역에 있는 명령어들이 하나씩 수행될 때 사용되어지는 메모리는 크게 스택과 힙 메모리가 있습니다.
스택 메모리(stack memory)는 프로그램의 함수나 메서드가 호출 될때 해당 사용되는 지역변수, 매개변수, 반환 값이 차지하는 공간입니다. 함수가 호출 될때 생겨나고 함수의 호출이 끝나면 저절로 사라지게 되는 공간입니다. 따라서 함수 별로 사용하는 공간이 다르게 되므로 하나의 함수는 다른 함수의 변수를 알 수 없습니다. 우리가 재귀 함수를 잘못 구현 했을때 stack overflow 오류가 뜨고 프로그램이 다운되는것은 끝나지 않는 재귀 호출로 인하여 해당 프로세스가 사용할 수 있는 스택 메모리 공간을 모두 사용했기때문입니다. 함수의 호출이 끝나면 자동으로 해제되는 공간이므로 특별이 메모리를 수거하거나 지우는 작업은 필요 없습니다.
힙 메모리 (heap memory)는 동적 메모리라고도 불리며 프로그래머가 직접 메모리를 할당받아 사용하게 됩니다. 프로그래밍 언어에 따라 new (자바, C++, C#) 나 malloc (C 언어) 에 의해 메모리를 할당 받습니다. 할당받은 메모리는 프로그램 전반에서 해당 주소를 참조 할 수 필요가 있을때 사용하게 되며 더이상 필요하지 않은 경우 프로그래머가 직접 해제하여야 합니다. C언어에서는 해당 메모리의 시작 주소(malloc()에서 반환 받은 포인터 값)를 이용하여 free()를 호출해줘야 하고 C++에서는 delete키워드로 메모리를 해제해줍니다.
단, 자바의 경우에는 이를 프로그래머가 아닌 자바의 gabage collector라는 쓰레드가 그 역할을 수행합니다. 힙에 생성된 인스턴스나 배열이 더이상 참조 되지 않는다는 것이 명시적일때 gabage collector가 메모리를 수거합니다. 따라서 자바로 프로그래밍 할 때는 new한 객체의 메모리 수거에 대한 코드를 구현하지 않습니다. 동적 메모리를 C나 C++에서 할당 받고 제대로 해제되지 않으면 메모리 누수 현상(memory leak)이 발생하고 이는 프로그램이 구동중에 예기치 않은 종료(abort)가 일어날 수 있으므로 반드시 깨끗이 해제하여야 한답니다.
