Home > Java-Ecosystem > Java > 자바 메모리 구조와 변수, 메서드 종류

자바 메모리 구조와 변수, 메서드 종류
Java JVM

자바 메모리 구조

  • 메서드 영역
    • 프로그램을 실행하는데 필요한 공통 데이터를 관리
    • 프로그램의 모든 영역에서 공유됨
    • 구성
      • 클래스 정보: 클래스 실행 코드 (바이트 코드) - 필드, 메서드, 생성자 코드 등
      • 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로 선언된 메서드는 오버라이드 될 수 없다.

Reference

김영한의 실전 자바 - 기본편