자바의 메모리 구조는 크게 메서드 영역(Method Area), 스택 영역(Stack Area), 힙 영역(Heap Area) 3개로 나눌 수 있다.

- 메서드 영역(Method Area) - 클래스 정보를 보관한다. 설계도, 붕어빵 틀
- 스택 영역(Stack Area) - 실제 프로그램이 실행되는 영역. 메서드를 실행할 때 마다 쌓이는 구조
- 힙 영역 (Heap Area) - 객체가 생성되는 영역. new 를 통해 객체를 생성하면 힙 영역에 객체를 생성한다. 설계도나 붕어빵 틀을 이용하여 생성된 실체나 붕어빵이 존재하는 공간이다. 배열도 힙 영역에 생성된다.
위의 내용은 이해가 쉽도록 작성된 내용이고, 실제는 아래와 같다.

1. 메서드 영역 :
-> 프로그램 실행에 필요한 공통 데이터 관리. 프로그램의 모든 영역에서 공유
- 클래스 정보 : 클래스의 실행 코드, 필드, 메서드, 생성자 코드 등 모든 실행 코드 존재
- static 영역 : static 변수들 보관.
- 런타임 상수 풀 : 공통 리터럴 상수 보관
- 하나의 클래스에 100개의 객체를 생성해도, 각 객체의 변수는 힙 영역에 존재하지만, 메서드는 같은 메서드를 공유하기 때문에 메서드 영역에 존재하게 된다.
2. 스택 영역
- 스택 프레임 : 스택 영역에 쌓이는 하나하나의 메서드가 스택 프레임이다. 메서드가 종료되면 제거된다.
스택이라는 개념을 알고갈 필요가 있다. 정리하고 넘어가자. 스택(stack)은 큐(queue)와 항상 같이 나오는 개념이다. 스택은 밑이 막힌 상자, 큐는 밑이 뚫린 상자라고 이해하면 편하다.
1) 스택(Stack)
- 후입 선출(LIFO) : 가장 마지막에 넣은 것이 가장 처음 나옴
2) 큐(Queue)
- 선입 선출(FIFO) : 가장 먼저 넣은 것이 가장 처음에 나옴

아래는 스택 구조를 알아보기 위한 코드이다.
public class JavaMemoryMain1 {
public static void main(String[] args) {
System.out.println("main start");
method1(10);
System.out.println("main end");
}
static void method1(int m1){
System.out.println("method1 start");
int cal = m1 * 2;
method2(cal);
System.out.println("method1 end");
}
static void method2(int m2){
System.out.println("method2 start");
System.out.println("method2 end");
}
}
/* 실행 결과
main start
method1 start
method2 start
method2 end
method1 end
main end
*/
동작 순서 : main method 시작 - main method 내의 method1 실행 - method1 내의 method2 실행 - method 2 끝 - method1 끝 - main method 끝
3. 힙 영역
-> 객체와 배열이 생성되는 영역. GC가 이루어지는 영역이다.
public class Data {
private int value;
public Data(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
public class JavaMemoryMain2 {
public static void main(String[] args) {
System.out.println("main start");
method1();
System.out.println("main end");
}
private static void method1() {
System.out.println("method1 start");
Data data1 = new Data(10);
method2(data1);
System.out.println("method1 end");
}
static void method2(Data data2) {
System.out.println("method2 start");
System.out.println("data.value() = " + data2.getValue());
System.out.println("method2 end");
}
}
동작 순서 : main 시작 - 메인 메서드 내의 method1 시작 - method1 내의 method2 시작 - method2 종료 - method1 종료 - main 종료
핵심 : method1 이 종료됨과 동시에 data1이라는 변수가 참조하는 곳도 사용되는 곳도 없다. 이 때 GC는 참조가 모두 사라진 인스턴스를 찾아서 메모리에서 제거한다.
'JAVA' 카테고리의 다른 글
| [자바/JAVA] final(상수) (3) | 2024.06.13 |
|---|---|
| [자바/JAVA] Static변수와 Static메서드 (0) | 2024.06.13 |
| [자바/JAVA] 접근 제어자(Access Modifier)와 캡슐화(Encapsulation) (2) | 2024.06.12 |
| [자바/JAVA] 생성자(Constructor) (0) | 2024.05.26 |
| [자바/JAVA] - 객체 지향 프로그래밍(OOP) - 캡슐화 (1) | 2024.05.25 |