Dev Language/Java

[자바/기본] 7. 자바 메모리 구조와 final

ydin 2024. 1. 16. 12:34

static과 자바 메모리 구조를 모호하게 알고 있었는데, 강의로 완전히 이해한 것 같다. 

static을 알기 위해서는 자바의 메모리 구조를 알아야 한다! 

 

자바 메모리 구조

자바의 메모리 구조는 크게 3가지로 나뉘는데, 각각 메서드 영역, 스택 영역, 힙 영역이 있다.

 

메서드 영역

프로그램을 실행하는데 필요한 **공통 데이터(클래스 정보, static, 상수)**를 관리한다.

이 영역은 프로그램의 모든 영역에서 공유한다.

  • 클래스 정보 : 클래스 실행 코드(바이트 코드), 필드/메서드/생성자 코드 같은 모든 실행 코드
  • static 영역 : static 변수 보관
  • 런타임 상수 풀 : 프로그램 실행에 필요한 공통 리터럴 상수(ex. “hello”) 보관
  • 메서드 영역과 인스턴스

 

스택 영역

실제 프로그램이 실행되는 영역이고, 메서드 호출과 지역변수(매개변수 포함)를 관리한다.

스레드 수만큼 스택 영역이 생성되고, 메서드 실행할 때마다 스택 프레임이 하나씩 쌓인다.

메서드가 종료되면 스택 프레임이 제거되고, 이때 지역 변수도 함께 제거된다.

스택 프레임이 모두 제거되면 프로그램도 종료된다.

  • 스택 프레임

 

힙 영역

객체(인스턴스), 배열이 생성되고 **GC(가비지 컬렉션)**이 이뤄지는 영역이다.

  • GC의 대상이 되는 조건

 

static 변수

static은 공통으로 사용되는 변수 혹은 메서드가 있을 때 사용하는 키워드로, 메서드 영역에서 관리하는 변수이다. 클래스 자체에 소속되어 있다. 멤버 변수나 메서드, 클래스 앞에 붙을 수 있다.

 

  • static 멤버 변수
    • static 변수, 정적 변수, 클래스 변수라고도 부른다
    • 메서드 영역에서 관리 한다
    • 생성주기는 프로그램 실행 시점에 딱 한번 만들어지고, 프로그램 종료 시점에 제거된다

 

  • static 변수 접근 방법
    • 클래스명.변수명 (ex. Data.count)

 

  • 필드 종류
    • 인스턴스 변수
      • static이 붙지 않음
      • 인스턴스를 생성해야 접근할 수 있는 변수이고, 인스턴스에 소속되어 있다
      • 인스턴스 생성할 때마다 새로 생성된다
    • 클래스 변수
      • static이 붙은 멤버 변수
      • 인스턴스 생성 없이 접근 가능한 변수이고, 클래스 자체에 소속되어 있다
      • 자바 프로그램 시작 시 딱 1개만 생성되고, 여러 곳에서 공유될 수 있다

 

static 메서드

메서드만 존재하는 클래스인 경우 굳이 인스턴스를 생성하고 메서드에 접근하는 것이 불필요할 수 있다. 이 경우 클래스 안에 메서드를 static으로 설정해 인스턴스 설정 없이 메서드에 접근할 수 있게 하는 것이 더 좋은 방법일 수 있다.

static 메서드는 클래스 레벨에서 호출할 수 있어서 정적 메서드 혹은 클래스 메서드라고도 한다.

 

  • 예시
public class DecoUtil2 {
	
    public static String deco(String str) {
        return "*" + str + "*";
    }
}

// static 메서드 호출
DecoUtil2.deco("hello"); -> 인스턴스 생성없이 메서드에 접근할 수 있다

 

 

  • 정적 메서드 사용법
    • static 메서드는 static만 사용 가능
      • static 자체가 메서드 영역에 속하기 때문에 같은 클래스 영역에 있는 정적 변수/메서드만 접근 가능
      • static 메서드는 정적 메서드, 정적 변수만 사용 가능
      • static 메서드가 인스턴스 변수/메서드를 사용할 수 없다
    • 모든 곳에서 static을 호출할 수 있다
      • static 메서드는 공용 기능이기 때문에 모든 곳에서 static을 호출할 수 있다

 

정적 메서드가 인스턴스 변수/메서드를 호출할 수 없는 이유

정적 메서드는 클래스의 이름으로 바로 호출하기에 인스턴스처럼 참조값의 개념이 없다. 하지만 인스턴스에 접근하려면 참조값(주소값)을 알아야 하는데, 정적 메서드는 참조값 없이 호출하기 때문에 정적메서드는 인스턴스 변수/메서드를 호출할 수 없다.

 

Reference

인프런 '김영한의 실전 자바 - 기본편'