값이 직접 저장되므로 접근 속도가 빠름
null 할당 불가
할당 시 값 복사
int a = 10;
int b = a;
a = 20;
new 키워드를 통해 객체를 생성할 때 Heap 메모리에 할당
null 값 할당 가능
할당 시 주소값 (참조값)이 복사
- 여러 변수가 하나의 동일한 객체를 참조 가능
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr1[0] = 100; // arr2[0]도 100

Stack Memory (Thread별 독립적)
┌─────────────────────────────┐
│ method2() Frame │ ← 현재 실행 중인 메서드
│ - Local Variables: b=20 │
│ - Parameters: param=10 │
│ - Return Address │
├─────────────────────────────┤
│ method1() Frame │
│ - Local Variables: a=10 │
│ - Reference: str → Heap │ (str 변수는 Stack에, "Hello" 문자열 객체는 Heap에)
│ - Return Address │
├─────────────────────────────┤
│ main() Frame │
│ - Parameters: args[] │
│ - Return Address │
└─────────────────────────────┘
Heap Memory
┌─────────────────────────────────────────────────────────┐
│ Young Generation │ (전체 Heap의 약 1/3)
├─────────────┬─────────────┬─────────────────────────────┤
│ Eden │ Survivor 0 │ Survivor 1 │
│ Space │ (S0) │ (S1) │
│ │ │ │
└─────────────┴─────────────┴─────────────────────────────┘
↓ (객체의 'Age' 임계값 도달 시)
┌─────────────────────────────────────────────────────────┐
│ Old Generation │ (전체 Heap의 약 2/3)
│ (Tenured Space) │
│ │
└─────────────────────────────────────────────────────────┘
지역 변수가 선언된 블록의 스코프를 벗어날 때
public void scopeExample() {
{
String localString = new String("지역변수");
} // 이 블록을 벗어나면 localString 참조가 해제되어 GC대상이 됨
}
참조를 null로 설정할 때
public void nullReferenceExample() {
String data = new String("데이터");
data = null; // "데이터" 객체에 대한 참조가 끊어져 GC 대상이 됨
}
컬렉션에서 제거될 때
public void collectionExample() {
List<String> list = new ArrayList<>();
list.add(new String("항목1"));
list.add(new String("항목2"));
list.clear(); // 리스트의 모든 요소에 대한 참조가 끊어지고 GC 대상이 됨
}
// 발생 조건: Eden Space가 가득 찰 때
public class MinorGCTrigger {
public static void triggerMinorGC() {
List<byte[]> list = new ArrayList<>();
// Eden Space를 빠르게 채움
for (int i = 0; i < 1000; i++) {
byte[] data = new byte[1024 * 1024];// 1MB씩
list.add(data);
if (i % 100 == 0) {
System.gc();// 힌트만 제공, 강제 실행 안됨
}
}
}
}
```
### Major GC (Old Generation)
```java
// 발생 조건: Old Generation이 가득 찰 때
public class MajorGCTrigger {
private static List<byte[]> longTermStorage = new ArrayList<>();
public static void triggerMajorGC() {
// Old Generation에 많은 객체 축적
for (int i = 0; i < 1000; i++) {
byte[] data = new byte[1024 * 1024];
longTermStorage.add(data);
// Minor GC를 여러 번 견딘 객체들이// Old Generation으로 승격됨
}
// Old Generation 가득참 → Major GC 발생
}
}
