위로
아래
Java 메모리 모델
기본형 변수 타입 = stack 영역
클래스 = class method 영역
static 붙은 경우 = class method 영역
객체(Object) = heap 영역
자바 메모리 관리법 : 서로 영역을 나누어서 메모리를 관리
stack
heap : 객체 저장 영역
class method 영역 (똑같은 이름의 개체는 1개만 생성된다. 클래스일 수도 있고 static일 수도 있어서 중복을 막는다)
메서드 영역
메서드(method) 영역
- 특징
- 프로그램 시작 전에 로드되고, 프로그램 종료 시 소멸
- 프로그램은 가장 먼저 static들을 찾아내어 메서드 영역 안의 스태틱 영역에 저장한다.
- JVM은 무조건 메서드 영역 안의 스태틱 영역 안의 main 메서드를 가장 먼저 실행시킨다. 스태틱 영역 안에 main 메서드가 없다면 프로그램은 실행되지 않는다. (또한, public으로 접근이 가능해야 한다)
- static 키워드를 통해 static 영역에 할당된 메모리는 모든 객체가 공유하는 메모리가 되지만, Garbage Collector의 영역 밖이라서 프로그램 종료 시까지 메모리가 할당된 채로 남아 있어, 시스템의 퍼포먼스에 악영향을 준다
- 메서드 영역에 저장되는 메모리 종류
- 프로그램 실행 코드
- 스태틱 변수, 스태틱 메소드
- 런타임 상수 풀
스택 영역
스택(stack) 영역
- 특징
- 지역 변수, 매개 변수가 프레임 형태로 생성되어 쌓였다가, 다 쓰면 사라진다.
- 정적인 데이터들이 저장된다 (기본 자료형처럼 정해진 크기의 값들만 저장된다)
- 프레임 영역을 벗어난 다른 메서드의 변수들은 서로 참조할 수 없다.
- 나중에 쌓인 메소드 프레임이 먼저 사라진다. (main method frame보다 adder method frame이 나중에 쌓였고, 먼저 빠졌다)
- 모든 method frame이 사라지면 프로그램이 종료된다. (가장 먼저 생성되어 가장 마지막에 사라지는 method frame이 main 메소드)
- 스택 영역에 저장되는 메모리 종류
- 지역 변수, 매개 변수를 포함한 메서드 프레임
예시
더보기
public class Ex05 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
int result = adder(num1, num2);
System.out.println(result);
}
public static int adder(int a, int b) {
return a + b;
}
}
힙 영역
힙(heap) 영역
- 특징
- 연산이 시작될 때 메모리 할당 시작
- new 연산자에 의해 생성되는 요소들이 힙 영역에 저장.
- 클래스마다 크기가 천차만별이라, 스택 영역과는 다르게 힙 영역은 데이터들이 동적으로 저장된다.
- 참조 변수를 통해 클래스를 사용하면, 스택 영역에는 정적 데이터만 올 수 있기에, 스택 영역에 생긴 참조 변수가 동적 클래스의 주소를 가리킨다. (주소는 정적인 데이터로 표현 가능)
- 가비지 콜렉터(garbage collector)에 의해 사용 없음이 확인되면 자동으로 제거.
- 실무에서는 heap 영역이 중요하다. heap 영역이 작으면 메모리 여유가 별로 없어서 가비지 콜렉터가 자주 작동하느라 프로그램이 느려진다.
- 힙 영역에 저장되는 메모리 종류
- 클래스의 객체 (인스턴스)
- 클래스의 배열
가비지 콜렉션
가비지 콜렉션 (garbage collection)
- 가비지 콜렉션이 수행되는 동안엔 모든 스레드가 멈춘다.
- 가비지 콜렉션은 별도의 알고리즘으로 수행된다. 개발자는 가비지 콜렉션이 언제 얼마큼 작동될지 알 수 없다.
- 가비지 콜렉션이 수행된다고 힙 메모리의 객체를 반드시 삭제하진 않는다. 표시만 해두고 나중에 삭제하기도 한다.
- 프로그램이 종료할 때까지 가비지 콜렉션이 수행되지 않을 수도 있고, 수행되더라도 객체를 삭제하지 않을 수도 있다.
- 프로그램이 종료되면, 운영체제 차원에서 힙 메모리의 객체들을 모두 제거하고 메모리를 회수한다.
- 실시간 시스템에서는 가비지 콜렉션이 수행되면 프로그램이 예측 불가능하게 정지될 수 있으니, 가급적 가비지 콜렉션을 수행하지 않는 방향으로 프로그램을 작성해야 한다.
- 가비지 콜렉션을 강제로 발생시키는 코드 : System.gc();
- 가비지 콜렉션이 객체를 강제로 지우도록 하는 코드 : System. runFinalization();