프로그래밍
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에 저장
}
}
- main 메서드 호출
- persion: Stack에 저장된 참조 변수
- Person 객체와 인스턴스 변수(name, age)는 Heap에 저장
- introduce 메서드 호출
- greeting: Stack에 저장된 로컬 변수
- name: Heap에 저장된 Person 객체의 인스턴스 변수
- 메서드 종료
- 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 객체를 참조
요약
- Heap
- 객체와 인스턴스 변수가 저장
- 객체의 생명 주기는 참조 여부에 따라 결정되며 Garbage Collector에 의해 해제
- Stack
- 메서드 호출시 생성되는 로컬 변수와 참조 변수가 저장
- 메서드 실행 동안에만 존재하며 메서드 종료시 자동으로 해제
- 차이점
- Heap은 장기적으로 데이터를 유지하고 공유 가능
- Stack은 메서드 실행과 함께 빠르게 생성 및 제거