프로그래밍

Heap과 Stack

바이오닉크로니클 2024. 12. 12. 13:16

Heap과 Stack의 차이

특징 Heap Stack
저장되는 데이터 객체와 인스턴스 변수(필드) 메서드 호출시 생성되는 로컬 변수 및 객체의 참조 변수
생명 주기 프로그램 실행 중 객체가 참조되는 한 유지 메서드 호출이 끝나면 자동으로 해제
메모리 위치 전역적으로 관리되는 메모리 영역 각 스레드의 독립적인 메모리 영역
가비지 컬렉션 더 이상 참조되지 않는 객체를 Garbage Collector가 자동으로 해제 Garbage Collection이 필요하지 않음. 메서드 종료시 자동으로 제거.
속도 메모리 할당/해제 속도가 느림 메모리 할당/해제 속도가 빠름
공유 여부 모든 스레드가 공유 스레드마다 독립적

Heap(객체와 인스턴스 변수)

public class Example {
    int instanceVar; // 인스턴스 변수 (Heap에 저장)

    public Example(int value) {
        this.instanceVar = value;
    }
}

instanceVar는 객체가 Heap에 생성될 때 할당된다.
객체가 삭제되기 전까지 instanceVar는 메모리에 유지된다.

Stack(로컬 변수와 참조 변수)

  • 로컬 변수
    • 메서드 내에서 선언된 변수로 해당 메서드의 실행 동안에만 Stack에 저장된다.
    • 메서드가 종료되면 로컬 변수는 자동으로 해제된다.
  • 참조 변수
    • 객체를 참조하는 변수로 Stack에 저장되지만 실제 객체는 Heap에 저장된다.
    • 참조 변수는 객체의 주소를 가리키며, 메서드가 종료되면 해제된다.
public class Main {
    public static void main(String[] args) {
        Example obj = new Example(42); // obj는 Stack에, 객체는 Heap에 저장
        int localVar = 10;             // localVar는 Stack에 저장
    }
}
  • obj: Stack에 저장된 참조 변수. Heap에 생성된 Example 객체를 가리킴
  • localVar: Stack에 저장된 로컬 변수

Heap과 Stack 데이터 흐름

public class Person {
    String name;  // 인스턴스 변수 (Heap에 저장)
    int age;      // 인스턴스 변수 (Heap에 저장)

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        String greeting = "Hello";  // 로컬 변수 (Stack에 저장)
        System.out.println(greeting + ", my name is " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 25); // person은 Stack에, 객체는 Heap에
        person.introduce();                     // 메서드 실행 중 greeting은 Stack에 저장
    }
}
  1. main 메서드 호출
  • persion: Stack에 저장된 참조 변수
  • Person 객체와 인스턴스 변수(name, age)는 Heap에 저장
  1. introduce 메서드 호출
  • greeting: Stack에 저장된 로컬 변수
  • name: Heap에 저장된 Person 객체의 인스턴스 변수
  1. 메서드 종료
  • greeting은 Stack에서 제거
  • Person 객체는 Heap에 유지(더 이상 참조되지 않으면 GC가 해제)

로컬 변수와 인스턴스 변수의 비교

특징 로컬 변수(Stack) 인스턴스 변수(Heap)
선언 위치 메서드 내부에 선언 클래스 내부에 선언
저장 위치 Stack 메모리 Heap 메모리
생명 주기 메서드 실행 중에만 존재 객체가 존재하는 동안 유지
기본 초기화 여부 초기화되지 않으면 사용할 수 없음(컴파일 오류 발생) 자동으로 초기화됨(기본값 설정)
예제 int localVar = 10; int instanceVar = 0;

참조 변수와 객체의 관계

Stack의 참조 변수는 Heap에 있는 객체를 가리키는 주소를 저장한다.
하나의 객체를 여러 참조 변수가 가리킬 수 있다.

public class Example {
    int value;
}

public class Main {
    public static void main(String[] args) {
        Example obj1 = new Example(); // obj1은 Stack, 객체는 Heap
        Example obj2 = obj1;          // obj2는 Stack에 있고, obj1과 같은 객체를 참조
        obj1.value = 42;
        System.out.println(obj2.value); // 출력: 42
    }
}
  • Heap 상태
    • 하나의 Example 객체가 생성
    • value = 42
  • Stack 상태
    • obj1과 obj2는 같은 Heap 객체를 참조

요약

  1. Heap
  • 객체와 인스턴스 변수가 저장
  • 객체의 생명 주기는 참조 여부에 따라 결정되며 Garbage Collector에 의해 해제
  1. Stack
  • 메서드 호출시 생성되는 로컬 변수와 참조 변수가 저장
  • 메서드 실행 동안에만 존재하며 메서드 종료시 자동으로 해제
  1. 차이점
  • Heap은 장기적으로 데이터를 유지하고 공유 가능
  • Stack은 메서드 실행과 함께 빠르게 생성 및 제거