자바 메모리 구조
-
메서드 영역
- 프로그램을 실행하는데 필요한 공통 데이터를 관리
- 프로그램의 모든 영역에서 공유됨
- 구성
- 클래스 정보: 클래스 실행 코드 (바이트 코드) - 필드, 메서드, 생성자 코드 등
-
static
영역:static
변수, 메서드, 클래스들을 보관 (프로그램 시작부터 끝까지 메모리 할당) - 런타임 상수 풀: 프로그램을 최적화하기 위해 공통 리터럴 상수를 보관
-
스택 영역
- 실제 프로그램이 실행되는 영역
- 실행 스택을 생성하고 메서드가 호출될 때마다 스택에 스택 프레임을 쌓는다. 메서드가 종료되면 스택프레임을 제거한다.
- 지역변수, 중간 연산 결과, 메서드 호출 정보 등이 스택 프레임에 포함된다.
-
처음 자바를 실행하면
main()
을 실행하기 위해 실행 스택에main()
스택 프레임을 하나 생성한다.
-
힙 영역
-
인스턴스가 생성되는 영역 (
new
명령어를 사용하면 여기를 사용) - 가비지 컬렉션이 이루어지는 영역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거된다.
-
인스턴스가 생성되는 영역 (
메서드 코드의 위치
객체가 생성될 때, 인스턴스 내부 변수 값은 각각 힙 영역에 할당되어 독립적으로 존재하지만, 메서드는 새로운 메모리 할당없이 공통된 코드를 공유한다. 따라서, 인스턴스 메서드를 호출하면 실제로는 메서드 영역에 있는 코드를 힙 영역으로 불러와서 수행한다.
단, static 메서드는 메서드 영역의 클래스 정보 코드를 사용하겠지만, 실행도 메서드 영역의 클래스 정보에서 한다.
멤버 변수의 종류
-
인스턴스 변수 (
static
이 붙지 않음)- 각각의 인스턴스에 독립적으로 소속되어 있는 변수
-
static 변수 (
static
이 붙음)- 클래스 자체에 소속되어 공용으로 함께 사용할 수 있는 변수
-
static 변수
=정적 변수
=클래스 변수
- 메서드 영역 (static 영역)에서 관리
-
클래스명
+.
으로 접근 (자신의 클래스에 있는 정적 변수라면 클래스명 생략 가능) -
처음 자바가 로딩될 때 하나만 생성
- 일반적으로 자바 프로그램이 실행되고 JVM이 처음 뜰 때, 클래스 정보를 메소드 영역에 모두 불러 들이고, static이 붙은 변수들은 메모리(static 영역)에 할당해버린다. 이런 static 변수들은 이 때 딱 하나 만들어지고 Java가 끝날 때까지 계속 쓸 수 있다.
변수의 생명주기
- 지역변수(매개변수 포함): 스택 영역의 스택 프레임에 존재 (메서드 종료 시 소멸)
- 인스턴스 변수: 힙 영역에 존재 (GC 발동 시 소멸)
- 클래스 변수: 메서드 영역의 static 영역에 존재 (JVM 종료 시 소멸)
지역변수 < 인스턴스 변수 < 클래스 변수
지역 변수가 제일 짧고, 클래스 변수가 제일 길다.
static이 정적인 이유
힙 영역에 생성되는 인스턴스 변수는 런타임에서 동적으로 생성되고 제거되지만, static 변수는 프로그램 시작 시점에 만들어지고 프로그램 종료 시점에 제거되므로 상대적으로 매우 정적이다.
멤버 메서드의 종류
-
인스턴스 메서드 (
static
이 붙지 않음)- 인스턴스에 소속되어 인스턴스를 생성해야 사용할 수 있는 메서드
-
static 메서드 (
static
이 붙음)- 클래스에 소속되어 클래스에 바로 접근해 사용할 수 있는 메서드
-
static 메서드
=정적 메서드
=클래스 메서드
- 인스턴스 변수를 필요로 하지 않는 단순 기능만 제공하는 경우 사용 (유틸리티성 메서드)
-
static 메서드는 static만 사용할 수 있다.(정적변수나 정적 메서드)
-
main()
가 대표적 정적 메서드 (main()
이 같은 클래스에서 호출하는 메서드도 정적 메서드)
-
- 자주 호출해야 한다면
static import
를 통해 클래스 명을 생략하고 메서드를 호출할 수 있다.
final
- 변수에
final
키워드가 붙으면 더는 값을 변경할 수 없다. - 특정 변수의 값을 할당한 이후 변경하지 않아야 한다면 사용하자. (고객 id 같은 부분)
- 의미 있는 경우
-
static final
필드(클래스 멤버 변수)를 필드 초기화 하는 것 (메모리 중복 없음)-
상수도
static final
을 지정한다.
-
상수도
-
생성자를 이용해서
final
필드(인스턴스 멤버 변수)를 초기화 하는 것
-
- 의미 없는 경우
-
final
필드(인스턴스 멤버 변수)를 필드 초기화 하는 것 (인스턴스마다 값이 중복되어 메모리 낭비)
-
- 클래스
final
- 상속의 끝을 의미, final로 선언된 클래스는 상속할 수 없다.
- 메서드
final
- 오버라이딩의 끝을 의미, final로 선언된 메서드는 오버라이드 될 수 없다.