자바의 메모리 영역
•
자바 프로그램이 실행되면 JVM(Java Virtual Machine)이 OS로부터 메모리를 할당 받은 후 용도에 따라 여러 영역으로 나누어 관리한다.
•
JVM의 메모리 공간(Runtime Data Area)은 크기 Method(Static) 영역, Stack 영역, Heap 영역으로 구분되고, 데이터 타입(자료형)에 따라 각 영역에 할당된다.
자바의 변수
•
자바에서는 변수가 선언된 위치에 따라 클래스 변수, 인스턴스 변수, 지역변수, 매개변수로 나뉜다.
public class Main {
public static void main(String[] args) { // 매개변수
int num == 1234; // 지역변수
}
}
public class Person {
private String name = "person1"; // 인스턴스 변수
public static int age = 28; // 클래스 변수
}
Java
복사
변수명 | 선언 위치 | 생성 시기 | 설명 |
클래스 변수(static 변수) | 클래스 영역 | 클래스가 메모리에 올라갈 때 | 클래스 영역에서 static으로 선언된 변수
객체를 공유하는 변수로, 여러 객체에서 공통으로 사용할 수 있다. |
인스턴스 변수 | 클래스 영역 | 인스턴스가 생성될 때 | 클래스 영역에서 static이 아닌 변수
객체/인스턴스마다 별도의 값을 가진다. |
지역변수 | 메서드 영역 | 메서드 수행 시 | 메서드 내에 선언되고 메서드가 끝나면 소멸되는 변수 |
매개변수 | 메서드 영역 | 메서드 수행 시 | 메서드 호출 시 값을 전달하는 변수
지역변수처럼 메서드가 끝나면 소멸된다. |
Method(Static) 영역
•
JVM이 동작해서 클래스가 로딩될 때 생성되는 영역으로, 클래스 변수(static 변수), 생성자, 메서드 등을 저장한다.
•
Method 영역은 어디서나 접근 가능하고, Mehtod 영역의 데이터는 프로그램의 시작부터 종료까지 메모리에 남아있는다.
•
static 메모리에 있는 데이터는 프로그램 종료 전까지 어디서든 사용이 가능하지만, 무분별하게 사용할 경우 메모리 부족 현상이 발생한다.
Stack 영역
•
메서드 내에서 정의된 변수 중 원시(Primitive) 타입의 지역 변수나 매개변수, 반환값의 데이터가 저장되는 공간이다.
•
메서드가 호출될 때 스택 영역에 스택 프레임이 할당되고 그 안에 메서드 내에서 선언된 지역변수와 매개변수들이 메서드의 스택 프레임 내에 저장된다.
•
메서드가 종료되면(스코프(scope) 범위에서 벗어나면) 스택 영역에서 해당 메서드의 스택 프레임이 해제된다.
Heap 영역
•
JVM이 관리하며 런타임 시 동적으로 할당하여 사용하는 영역으로, 참조형(Reference) 타입의 객체(인스턴스)와 배열 등이 저장된다.
•
객체가 선언되면 힙 영역에 해당 객체를 저장하고, 스택 영역에 해당 힙 메모리의 주소값을 저장(참조)하고 있는다.
•
힙 영역은 스택 영역과는 다르게 선언한 메서드가 종료되어도 삭제되지 않고 유지된다.
•
힙 영역의 메모리는 스택 영역의 어떤 참조 변수도 해당 인스턴스를 참조하지 않는다면 가비지 컬렉터에 의해 메모리가 해제된다.
•
멀티 스레드에서 스택 영역은 스레드마다 별개로 생성되지만, 힙 영역은 스레드 개수와 상관없이 하나만 존재한다.
동작 예시
1.
처음 프로그램 동작 시 static 변수들과 클래스, 메서드 등을 Method 영역에 저장
2.
main 메서드 동작 시 main 스택 프레임 생성 및 지역/매개변수들 저장
3.
Counter 클래스의 객체(인스턴스) 생성(힙 영역에 할당, 저장 후 스택 영역에 메모리 주소 참조)
4.
twice 메서드 수행 시 스택 영역에 스택 프레임 생성 및 매개변수 저장
5.
plus 메서드 실행으로 각각 스택 프레임 생성 및 참조 주소를 통해 힙 영역의 데이터 변경
6.
get 메서드 수행 및 반환값 저장
7.
main 메서드 종료
8.
가비지 컬렉터가 어디서도 참조하고 있지 않는 Counter 인스턴스 청소