Java - memory & static

develkkm·2025년 9월 22일

0부터 시작하는 Java

목록 보기
16/27

메모리 구조와 static


1. 자바 메모리 구조

자바 프로그램은 실행될 때 JVM에 의해 메모리가 여러 영역으로 나뉜다.

  • 메서드 영역 (Method Area)
    클래스 정보, static 변수, 상수, 메서드 코드 등이 저장된다.
    모든 객체가 공유하며 프로그램이 끝날 때까지 유지된다.

  • 힙 영역 (Heap Area)
    new 키워드로 생성한 객체와 배열이 저장된다.
    GC(Garbage Collector)가 관리하며 참조가 끊긴 객체를 제거한다.

  • 스택 영역 (Stack Area)
    메서드 호출 시마다 스택 프레임이 쌓이고, 매개변수·지역 변수·중간 연산값 등이 저장된다.
    메서드 실행이 끝나면 해당 스택 프레임은 제거된다.


2. 스택과 힙의 사용

public class MemoryExample {
    public static void main(String[] args) {
        int local = 10;                 // 스택에 저장
        Data data = new Data("Hello");  // 참조 변수 data는 스택, 실제 객체는 힙
    }
}

class Data {
    String msg;
    Data(String msg) {
        this.msg = msg;
    }
}
  • local : 스택에 저장
  • data : 스택에 저장된 참조 변수, 힙 객체를 가리킴
  • msg : Data 객체의 필드이므로 힙에 저장

3. static 변수 (클래스 변수)

특징

  • 클래스 로딩 시점에 메서드 영역에 생성된다.
  • 인스턴스에 속하지 않고 클래스 자체에 속한다.
  • 모든 인스턴스가 값을 공유한다.
  • GC 대상이 아니므로 프로그램이 끝날 때까지 남는다.

예시

public class Counter {
    public static int count = 0; // 클래스 변수
    public String name;          // 인스턴스 변수

    public Counter(String name) {
        this.name = name;
        count++;
    }
}

Counter a = new Counter("A");
Counter b = new Counter("B");

System.out.println(Counter.count); // 2

4. static 메서드

특징

  • 인스턴스 생성 없이 호출 가능하다.
  • static 변수와 다른 static 메서드에는 접근할 수 있지만, 인스턴스 변수에는 접근할 수 없다.
  • 객체 상태와 무관한 연산을 수행할 때 적합하다.

예시

public class Calculator {
    public static int add(int x, int y) {
        return x + y;
    }
}

int result = Calculator.add(3, 7);

5. 유틸 클래스 예제

수학 유틸 클래스 예시를 통해 static 메서드의 장점을 살펴보자.

public class MathArrayUtils {

    private MathArrayUtils() {
        //private 인스턴스 생성을 막는다.
    }

    public static int sum(int[] values) {
        int total = 0;
        for (int value : values) {
            total += value;
        }
        return total;
    }

    public static double average(int[] values) {
        return (double) sum(values) / values.length;
    }

    public static int min(int[] values) {
        int minValue = values[0];
        for (int value : values) {
            if (value < minValue) {
                minValue = value;
            }
        }
        return minValue;
    }

    public static int max(int[] values) {
        int maxValue = values[0];
        for (int value : values) {
            if (value > maxValue) {
                maxValue = value;
            }
        }
        return maxValue;
    }
}
  • 객체 생성 없이 클래스명.메서드명() 형식으로 호출한다.
  • 배열 합계, 평균, 최소값, 최대값 같은 기능은 객체 상태와 무관하기 때문에 static 메서드로 제공하는 것이 적절하다.
profile
알던것을 더 확실하게

0개의 댓글