자바 메모리 구조는 메서드 영역, 힙 영역, 스택 영역 총 3가지로 나뉘어 있다.
메서드영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리한다.
- 클래스 정보: 클래스의 실행코드(바이트 코드), 필드, 메서드, 생성자 모든 실행코드 존재
- static영역: 객체를 생성하지 않고도 정적으로 사용할 수 있는 메서드
- 런타임 상수 풀: 리터럴 문자가 있으면 그것을 묶어서 관리할 수 있음.
스택 영역은 자바 실행했을 때 하나의 실행 스택이 생성된다.
스택 프레임은 지역변수, 중간 연산 결과, 메서드 호출 정보가 포함된다.
힙 영역은 객체(인스턴스)와 배열이 생성되는 영역이다.
가비지컬렉션(GC)이 이루어지는 주 영역이며 더 이상 참조하지 않는 객체는 GC에 의해 제거
자바 프로그램에서 특정 클래스 50개를 생성한다면 힙 메모리에 50개 생성이 된다.
각각의 인스턴스는 변수와 메서드를 가진다.
객체가 생성될 때 인스턴스 변수에는 메모리에 할당되지만 메서드에 대한 새로운 메모리 할당은 없다.
package memory;
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");
}
}
1. main 메서드 실행 -> 2. method1의 m1값과 cal값 넣기
-> 3. method1에 method2(cal) 호출을 하면서 m2의 값을 호출
-> 4. 호출이 끝나면 method2 종료 -> 5. 호출이 끝나면 method1 종료
-> 6. main 메서드 종료
package memory;
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");
}
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");
}
}
순서는 다음과 같다.
<후입선출방식 - 데이터 삽입방식>
- 즉, method1, method2를 호출하면 해당하는 참조값과 value값이 힙 영역으로 들어가게 된다.
1. 메인 메서드 실행
2. main start라는 문자를 콘솔에 출력
3. 메인메서드에 method1 호출
4. method1에 시작했다는 메시지를 콘솔에 출력하고 새 Data를 생성하여 data의 참조값과 실제 값을 data1에 보관한다.
5. 보관되어 있는 참조값과 인스턴스 값이 들어있는 data1에 method2를 호출
6. method2가 실행되었다는 메시지를 콘솔에 출력하고 data1값을 data2에 대입한다.
7. method2를 호출하면 data2의 value값이 호출.
8. method2가 종료되었다는 메시지를 출력한 후 method2의 데이터를 제거된다.
9. method1이 종료되면 method1의 데이터는 제거된다.
10. 메인 메서드가 종료되면 데이터는 제거된다.
제거된 인스턴스는 가비지컬렉션으로 인해 메모리에서 제거된다.
힙 영역 외부가 아닌 힙 영역 안에서만 인스턴스끼리 서로 참조하는 경우에도 GC 대상
지역변수는 스택 영역에 객체(인스턴스)는 힙 영역에 관리.
메서드 영역은 static과 관련이 있다.