[JAVA] 메모리 구조(static, stack, heap)
자바에서 사용되는 변수는 컴퓨터 내부의 메모리 공간에 저장됩니다.
메모리는 프로그램이 실행되는 작업공간을 말합니다. 즉 int num; 문장을 선언하면, 메모리에 4바이트(int형) 크기의 공간이 num이라는 이름으로 할당됩니다. 그리고 int num = 10; 이렇게 num의 값을 정해주면 num공간에 값 10을 넣게 되는 것입니다.
[출처]Doit! 자바프로그래밍 입문
메모리 공간은 크게 Stack(스택)영역, Static(스태틱)영역, Heap(힙) 영역으로 구분되고 데이터 타입에 따라서 해당 공간에 각각 할당됩니다.
1. Stack(스택)영역
함수가 수행될 때 그 함수만을 위한 메모리 공간이 할당되는데, 이 메모리 공간을 스택이라고 부릅니다. 스택메모리에 저장된 공간은 함수 수행이 끝나면 공간에서 자동으로 사라집니다. 스택영역은 원통의 한쪽이 막혀있는 형태의 메모리 공간으로 함수가 호출된 순서대로 메모리 공간에 들어오고 결과값이 반환되면 사라집니다. 예를 들어 A( ) -> B( ) -> C( ) 순서로 함수를 호출했다면 C( ) -> B( ) -> A( ) 순서로 반환되고 스택 메모리도 이 순서대로 소멸됩니다. 스택영역은 함수가 수행될 때 공간이 생기므로 메서드 내부에서 정의하는 지역변수가 바로 이 메모리 영역에 저장됩니다.
2. Static(스태틱)영역
클래스 전반에서 공통으로 사용할 수 있는 기준변수가 필요한 경우가 있는데, 이때 이 변수를 static변수라고 합니다. Static변수는 프로그램이 실행되어 메모리에 올라갔을때 딱 한번 메모리 공간이 할당되고 이 값은 모든 객체가 공유하게 됩니다. 그래서 static 변수는 다른 이름으로 정적변수 또는 클래스변수라고도 부릅니다. Static영역에 저장되는 변수는 객체의 생성과 상관없이 먼저 생성되어 있어서 기본적으로 프로그램에 깔려있는 처음부터 끝까지 계속 필요한 정보를 저장할 때 사용합니다.
3. Heap(힙)영역
클래스가 메모리 공간에 생성된 상태를 인스턴스 즉 객체라고 합니다. 또한 생성된 클래스의 인스턴스를 객체라고도 부릅니다. 바로 이때 인스턴스가 생성되는 메모리 공간을 Heap영역이라고 합니다. 클래스 생성자를 하나 호출하면 객체가 heap 메모리에 생성되는 것입니다. 이렇게 클래스에 선언한 멤버변수를 다른말로 인스턴스 변수라고 부릅니다.
예를 들어
Student studentAhn = new Student( );
위와 같이 생성된 클래스를 studnetAhn 변수에 대입하면 인스턴스가 저장된 메모리를 studentAhn 변수가 가리킵니다. 지역변수 studentAhn에 생성된 인스턴스를 대입하는 것은 studentAhn에 인스턴스가 생성된 Heap메모리의 주소를 대입한다는 것과 같은 의미입니다.
실제로 스택영역과 스태틱영역, 힙영역을 사용하는 순서를 확인해보면 다음과 같습니다.
1. 제일 먼저 static으로 선언된 num과 main을 Static 메모리에 올라갑니다.
2. main 메서드를 실행하면 지역변수인 minus가 Stack 메모리에 올라갑니다.
3. 마지막으로 new를 사용해서 Test1( )의 객체(인스턴스)를 선언했을 때 sum이 Heap메모리에 올라갑니다.
이때 메모리의 생성과 소멸주기를 확인해보면
Static 메모리는 프로그램이 종료될 때까지 유지되고 프로그램과 함께 종료됩니다.
다음으로 Stack 메모리는 메서드를 호출하면 메모리에 올라가서 호출이 완료되면 종료됩니다.
마지막으로 Heap메모리는 객체를 생성할때마다 각각의 메모리 공간이 할당되고 그 주소값을 가리키게 됩니다.
프로그램을 만들 때
시작부터 끝까지 유지돼야하는 메모리는 Static영역에, 여러번 생성되어야 하는 메모리는 Heap 영역에 만드는 것이 좋습니다.