F-lab Java 1์ฃผ์ฐจ / Phase 5 / Unit 5.4 ๋ณธ๊ฒฉ ํ์ต ์๋ฃ โ Phase 5 ๋ง๋ฌด๋ฆฌ!
9-์น์ ๋ง์คํฐ ํ๋กฌํํธ ํ์์ผ๋ก ๊น์ด ํํค์น๋ค.์ ์ ์ง์: Unit 5.3 (GC ์๊ณ ๋ฆฌ์ฆ 4๊ฐ์ง)
๋ค์ Phase: Phase 6 โ ๋ฐ์ดํฐ ๋ค๋ฃจ๊ธฐ (๋ฌธ์์ดยท์ปฌ๋ ์ )์ด Unit์ ์๋ฏธ: ์ด์ ํ๊ฒฝ์์ GC ๋ฅผ ์ ํํ๋ ์ค์ฉ ๊ฐ์ด๋.
Serial, Parallel, CMS, G1, ZGC, Shenandoah ์ ์ ํํ ์ฐจ์ด.
ILIC ์ด์์ ์ด๋ค GC ๊ฐ ๋ง๋์ง ๊ฒฐ์ ๊ฐ๋ฅ.
ํฐ ์ฌ๋ฌด์ค์ ์ฒญ์ ์๋น์ค ์ต์ :
โ ์ด๊ฒ ์๋ฐ GC ์ 6๊ฐ์ง ์ข ๋ฅ.
"GC ๋ ์๊ณ ๋ฆฌ์ฆ์ด ๊ฐ์๋ ๊ตฌํ (๋ฉํฐ ์ค๋ ๋, Concurrent, Region ๊ธฐ๋ฐ) ์ ๋ฐ๋ผ ๋ค์ํ ์ข ๋ฅ๋ก ์งํํ๋ค."
๊ฐ GC ์ trade-off:
๋น์ ์ ๋ฆฌ:
| ๋น์ | GC ์ข ๋ฅ | ์ ํฉ |
|---|---|---|
| 1์ธ ์ฒญ์๋ถ | Serial | ์์ ํ๊ฒฝ |
| ์ฒญ์ ํ | Parallel | ์ฒ๋ฆฌ๋ ์ฐ์ |
| ๋์ ์ฒญ์ | CMS | ์๋ต์ฑ (deprecated) |
| ๊ตฌ์ญ๋ณ ์ฒญ์ | G1 | ์ผ๋ฐ (๊ธฐ๋ณธ) |
| ๋ฉ์ถค ์๋ ์ฒญ์ | ZGC | ์ ์ง์ฐ |
GC ์ ํต์ฌ trade-off:
[์ฒ๋ฆฌ๋ (Throughput)] โโโโโโโโ [์๋ต์ฑ (Latency)]
๋ฐฐ์น, ๋๋ ์ฒ๋ฆฌ ์ฌ์ฉ์ ์๋ต
STW ๊ธธ์ด๋ OK STW ์งง์์ผ
ํ ๊ฐ์ง GC ๋ก๋ ๋ชจ๋ ํ๊ฒฝ ๋ง์กฑ ๋ถ๊ฐ:
โ ๋ค์ํ GC ๊ฐ ๋ฑ์ฅ.
์๋ฐ ๋ฒ์ ๋ง๋ค ๊ธฐ๋ณธ GC ๊ฐ ์งํ:
| ์๋ฐ ๋ฒ์ | ๊ธฐ๋ณธ GC |
|---|---|
| 1.0~1.4 | Serial |
| 1.5~1.7 | Parallel (Heap ํฐ ๊ฒฝ์ฐ) |
| 8 | Parallel โญ |
| 9~ | G1 โญ |
| 11~ | G1 (ZGC ์คํ์ ) |
| 15~ | G1 (ZGC ์ ์) |
| 17~ | G1 (Generational ZGC ์คํ์ ) |
| 21~ | G1 (Generational ZGC ์ ์) |
๋ฐ์น์ ๋์ Java 17 ํ๊ฒฝ:
โ ํฐ Heap ์์๋ ํจ์จ์ ์ธ GC ํ์.
"GC ์ข ๋ฅ ์ ํ์ '๋ด ํ๊ฒฝ์ ์ฐ์ ์์' ์ ๋ต์ด๋ค."
์ฒ๋ฆฌ๋์ธ๊ฐ ์๋ต์ฑ์ธ๊ฐ? ์์ Heap ์ธ๊ฐ ํฐ Heap ์ธ๊ฐ? ๋จ์ผ CPU ์ธ๊ฐ ๋ฉํฐ CPU ์ธ๊ฐ?
๋ชจ๋ ํ๊ฒฝ์ ๋ง๋ ๋จ์ผ GC ๋ ์๋ค. ์ํฉ์ ๋ง๊ฒ ์ ํ. ์๋์ด ๊ฐ๋ฐ์๋ผ๋ฉด ๊ฐ GC ์ ํน์ฑ์ ์๊ณ ํ๊ฒฝ์ ๋ง๋ ์ ํ ๊ฐ๋ฅํด์ผ.
GC ์ข ๋ฅ๋ฅผ ๋ชจ๋ฅด๋ฉด ์ด์ ํ๊ฒฝ์์ ๋ค์ํ ๋ฌธ์ ๋ฐ์.
java -jar ilic.jar # ๊ธฐ๋ณธ GC (Java 17 โ G1)
์๊ณ ์ฌ์ฉ: ์๋์ G1 ์ ํ โ
๋ชจ๋ฅด๊ณ ์ฌ์ฉ: ์ด๋ค GC ์ธ์ง๋ ๋ชจ๋ฆ โ
๋ฌธ์ ์:
java -XX:+UseG1GC -Xmx512m -jar small.jar
๋ฌธ์ :
java -XX:+UseParallelGC -jar webapp.jar
๋ฌธ์ :
ILIC ์๋น์ค:
- Heap: 4GB
- API ์๋ต ์๊ฐ SLA: P99 < 500ms
- ์ฌ์ฉ GC: ๋ชจ๋ฆ (๊ธฐ๋ณธ)
๋ฌธ์ :
๊ฐ๋ ์๋ต ์๊ฐ 2์ด โ SLA ์๋ฐ
GC ์ข ๋ฅ ๋ชจ๋ฅด๋ฉด:
GC ์ข ๋ฅ ์๋ฉด:
"ILIC ์์ ์ด๋ค GC ์ฌ์ฉํ๊ณ , ์ ๊ทธ GC ์ธ๊ฐ์?"
๋ต ๋ชปํจ:
์ ๋ตํจ:
๋ฌธ์ : Full GC ๋น๋ฒ, STW ๊น
GC ์ข ๋ฅ ๋ชจ๋ฅด๋ฉด:
GC ์ข ๋ฅ ์๋ฉด:
MaxGCPauseMillis)Java 8 โ Java 17 ๋ง์ด๊ทธ๋ ์ด์
๊ธฐ๋ณธ GC ๋ณ๊ฒฝ: Parallel โ G1
GC ์ข ๋ฅ ๋ชจ๋ฅด๋ฉด:
GC ์ข ๋ฅ ์๋ฉด:
| ์๋๋ฆฌ์ค | GC ์ข ๋ฅ ๋ชจ๋ฅด๋ฉด | GC ์ข ๋ฅ ์๋ฉด |
|---|---|---|
| ๊ธฐ๋ณธ GC ์ฌ์ฉ | ๋ฌด์ง์ | ์๋ ๋ช ํ |
| GC ์ ํ | ์๋ชป ์ ํ | ์ํฉ์ ๋ง๋ ์ ํ |
| ์ด์ ๋ถ์ | ๋ง๋งํจ | ์ ํํ ์ง๋จ |
| ๋ฉด์ | ํ๋ฝ | ์๋์ด ์ธ์ |
| ํ๋ | ์ต์ ๋ชจ๋ฆ | ๋ค์ํ ์ ํ์ง |
| ๋ฒ์ ์ ๊ทธ๋ ์ด๋ | ๋นํฉ | ๊ณํ์ |
โ GC ์ข ๋ฅ ์ดํด๋ ์๋์ด ์๋ฐ ๊ฐ๋ฐ์์ ํ์.
java -XX:+UseSerialGC -jar app.jar
java -XX:+UseParallelGC -jar app.jar
# ์ฒ๋ฆฌ๋ ๋ชฉํ
-XX:GCTimeRatio=99 # 1% ์ด๋ด GC
-XX:MaxGCPauseMillis=200 # ๋ชฉํ STW
java -XX:+UseConcMarkSweepGC -jar app.jar # โ Java 14+์์ ์ฌ์ฉ ๋ถ๊ฐ
[Heap]
โโโ Region 0 (Eden)
โโโ Region 1 (Survivor)
โโโ Region 2 (Old)
โโโ Region 3 (Humongous)
โโโ Region 4 (Free)
โโโ ... ์๋ฐฑ~์์ฒ Region
MaxGCPauseMillis)java -XX:+UseG1GC -jar app.jar
# ์ฃผ์ ํ๋ ์ต์
-XX:MaxGCPauseMillis=200 # ๋ชฉํ STW (๊ธฐ๋ณธ 200ms)
-XX:G1HeapRegionSize=4m # Region ํฌ๊ธฐ (์๋ ๊ณ์ฐ๋ OK)
-XX:InitiatingHeapOccupancyPercent=45 # Mixed GC ํธ๋ฆฌ๊ฑฐ
-XX:ConcGCThreads=2 # Concurrent ์ค๋ ๋ ์
java -XX:+UseZGC -jar app.jar
# Generational ZGC (Java 21+)
java -XX:+UseZGC -XX:+ZGenerational -jar app.jar
java -XX:+UseShenandoahGC -jar app.jar
| GC | ๋ฑ์ฅ | ์๊ณ ๋ฆฌ์ฆ | STW | ์ฒ๋ฆฌ๋ | ์ ํฉ ํ๊ฒฝ |
|---|---|---|---|---|---|
| Serial | 1.0 | ๋จ์ผ ์ค๋ ๋ | ๊น | ๋ณดํต | ์์ ํ๊ฒฝ, ๋จ์ผ CPU |
| Parallel | 1.4 | ๋ฉํฐ ์ค๋ ๋ | ๊น (๋จ์ถ) | ๋์ | ์ฒ๋ฆฌ๋ ์ฐ์ , ๋ฐฐ์น |
| CMS | 1.4 | Concurrent | ์งง์ | ๋ณดํต | (deprecated) |
| G1 | 7+, 9 default | Region | ๋ณดํต | ๋์ | ์ผ๋ฐ ๋ฐฑ์๋ โญ |
| ZGC | 11+ | Colored Pointer | ๋งค์ฐ ์งง์ | ๋ณดํต | ์ ์ง์ฐ, ํฐ Heap |
| Shenandoah | 12+ | Red Hat | ๋งค์ฐ ์งง์ | ๋ณดํต | ์ ์ง์ฐ, OpenJDK |
Heap ํฌ๊ธฐ?
โโโ ~100MB
โ โโโ Serial (๋จ์, ํจ์จ)
โ
โโโ 100MB ~ 4GB
โ โโโ ์ฒ๋ฆฌ๋ ์ฐ์ ?
โ โ โโโ Parallel
โ โโโ ์๋ต์ฑ ์ฐ์ ?
โ โโโ G1
โ
โโโ 4GB ~ 32GB
โ โโโ G1 (๊ธฐ๋ณธ ๊ถ์ฅ) โญ
โ
โโโ 32GB+
โโโ ์๋ต์ฑ ๋งค์ฐ ์ค์?
โโโ YES: ZGC
โโโ NO: G1
Case 1: ์ผ๋ฐ API ์๋ฒ (Heap 2~4GB):
java -XX:+UseG1GC \
-Xms2g -Xmx2g \
-XX:MaxGCPauseMillis=200 \
-jar ilic.jar
Case 2: ๋ฐฐ์น ์ฒ๋ฆฌ (๋์ฉ๋ ๋ฐ์ดํฐ):
java -XX:+UseParallelGC \
-Xms8g -Xmx8g \
-jar batch.jar
Case 3: ์ค์๊ฐ ์์คํ (์ ์ง์ฐ):
java -XX:+UseZGC \
-Xms16g -Xmx16g \
-jar realtime.jar
1. STW ์์ (๋ชจ๋ Application Thread ์ ์ง)
2. ๋จ์ผ GC ์ค๋ ๋๊ฐ Mark + Sweep + Compact
3. STW ์ข
๋ฃ
โ ๋จ์. ์์ Heap ์์๋ ์คํ๋ ค ๋น ๋ฅผ ์ ์์.
1. STW ์์
2. ์ฌ๋ฌ GC ์ค๋ ๋๊ฐ ๋ณ๋ ฌ๋ก Mark + Sweep + Compact
3. STW ์ข
๋ฃ
์ค๋ ๋ ์:
๊ธฐ๋ณธ: CPU ์ฝ์ด ์
์กฐ์ : -XX:ParallelGCThreads=N
โ STW ์๊ฐ = Serial ์ 1/N (N = ์ค๋ ๋ ์).
[G1 Heap]
โโโ Eden Region (์ฌ๋ฌ ๊ฐ)
โโโ Survivor Region (์ฌ๋ฌ ๊ฐ)
โโโ Old Region (์ฌ๋ฌ ๊ฐ)
โโโ Humongous Region (ํฐ ๊ฐ์ฒด)
โโโ Free Region (์ฌ์ฉ ๊ฐ๋ฅ)
1. Young GC (Minor GC):
2. Concurrent Marking:
3. Mixed GC:
4. Full GC (ํผํด์ผ ํ ):
[Heap]
โโโ Region A: 80% Garbage (target)
โโโ Region B: 30% Garbage
โโโ Region C: 90% Garbage (target)
โโโ Region D: 10% Garbage
โโโ ...
GC ์ฐ์ ์ฒญ์: Region A, C
โ ๊ฐ์ฅ ํจ์จ์ ์ธ Region ๋ถํฐ ์ฒญ์.
-XX:MaxGCPauseMillis=200:
์ผ๋ฐ 64-bit ํฌ์ธํฐ:
[ 64 bits (์ฃผ์) ]
ZGC ์ Colored Pointer:
[ 4 bits (color) ][ 60 bits (์ฃผ์) ]
Color ์๋ฏธ:
- Marked0: Live (์ด๋ฒ ์ฌ์ดํด)
- Marked1: Live (๋ค์ ์ฌ์ดํด)
- Remapped: ์ฌ๋ฐฐ์น๋จ
- Finalizable: finalize ๋์
โ ํฌ์ธํฐ ์์ฒด์ GC ์ ๋ณด ์ ์ฅ.
// ์ฌ์ฉ์ ์ฝ๋
Customer c = customers.get(0); // ๊ฐ์ฒด ์ฐธ์กฐ ์
// JVM ๋ด๋ถ (Load Barrier)
- ํฌ์ธํฐ ์์ ํ์ธ
- ํ์ ์ ๋์ ๋งํน
- ํ์ ์ ์ฌ๋ฐฐ์น ์ฒ๋ฆฌ
โ ๋งค ์ฐธ์กฐ ์ ์ฝ๊ฐ์ ์์ , ๊ทธ๋ฌ๋ STW ๊ฑฐ์ ์์.
1. Pause Mark Start (~1ms)
- GC Root ๋งํน
2. Concurrent Marking
- Application ๊ณผ ๋์ ์คํ
- Heap ์ ์ฒด ๋งํน
3. Pause Mark End (~1ms)
- ๋งํน ๋ง๋ฌด๋ฆฌ
4. Concurrent Relocation
- Live ๊ฐ์ฒด ์ฌ๋ฐฐ์น
- Application ๊ณผ ๋์
โ STW ๋ ์ ms ๋ง. Heap ํฌ๊ธฐ ๋ฌด๊ด.
| G1 | ZGC | |
|---|---|---|
| Region ํฌ๊ธฐ | 1~32MB | ~์ GB |
| STW | ~200ms (๋ชฉํ) | ~10ms ์ดํ |
| Heap | 4GB~์๋ฐฑ GB | ์ TB ๊ฐ๋ฅ |
| CPU ์ฌ์ฉ | ๋ณดํต | ์ฝ๊ฐ โ |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ | ๋ณดํต | ์ฝ๊ฐ โ |
| ์ฒ๋ฆฌ๋ | ๋์ | ์ฝ๊ฐ โ |
| ์ ํฉ | ์ผ๋ฐ ์๋ฒ | ์ ์ง์ฐ |
Concurrent GC ์ ์ฅ์ :
Concurrent GC ์ ๋จ์ :
โ ์๋ต์ฑ์ ์ํด ๋ค๋ฅธ ์์ ๋ ์ฌ์ฉ.
# ๋ฐฉ๋ฒ 1: PrintCommandLineFlags
java -XX:+PrintCommandLineFlags -version
# ์ถ๋ ฅ ์์:
# -XX:+UseG1GC โ ์ฌ์ฉ ์ค์ธ GC
# ๋ฐฉ๋ฒ 2: GC ๋ก๊ทธ
java -Xlog:gc -jar myapp.jar
# ์ถ๋ ฅ์์ GC ์ด๋ฆ ํ์ธ
# ์ผ๋ฐ ๋ฐฑ์๋ (Heap 2~4GB)
java -XX:+UseG1GC \
-Xms2g -Xmx2g \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/heap-dump.hprof \
-Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags \
-jar ilic.jar
public class GCBenchmark {
public static void main(String[] args) {
long start = System.currentTimeMillis();
List<byte[]> survivors = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) {
byte[] data = new byte[1024]; // 1KB
if (i % 1000 == 0) {
survivors.add(data);
}
}
long elapsed = System.currentTimeMillis() - start;
System.out.println("Total time: " + elapsed + "ms");
}
}
๋ค๋ฅธ GC ๋ก ์คํ:
# Serial
java -XX:+UseSerialGC GCBenchmark
# ์ถ๋ ฅ: ~3000ms (๋จ์ผ ์ค๋ ๋)
# Parallel
java -XX:+UseParallelGC GCBenchmark
# ์ถ๋ ฅ: ~1500ms (๋ณ๋ ฌ, ์ฒ๋ฆฌ๋ โ)
# G1
java -XX:+UseG1GC GCBenchmark
# ์ถ๋ ฅ: ~2000ms (๊ท ํ)
# ZGC
java -XX:+UseZGC GCBenchmark
# ์ถ๋ ฅ: ~2200ms (์๋ต์ฑ, ์ฒ๋ฆฌ๋ ์ฝ๊ฐ โ)
โ GC ์ ํ์ด ์ฑ๋ฅ์ ์ง๊ฒฐ.
# ์ด์ ํ๊ฒฝ โ ๊ฒ์ฆ๋ ์ค์
java \
# GC ์๊ณ ๋ฆฌ์ฆ
-XX:+UseG1GC \
# Heap ํฌ๊ธฐ (๊ณ ์ ๊ถ์ฅ)
-Xms4g -Xmx4g \
# ๋ชฉํ STW
-XX:MaxGCPauseMillis=200 \
# OOM ์ ์๋ ๋คํ
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/heap-dump-%t.hprof \
# GC ๋ก๊ทธ
-Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags:filecount=10,filesize=100M \
# ์ถ๊ฐ ๋ชจ๋ํฐ๋ง
-XX:+PrintTenuringDistribution \
-XX:+UnlockExperimentalVMOptions \
-jar ilic.jar
๋ฐ์น์ ๋์ด Java 17 ์ฌ์ฉ ์:
java \
-Xms2g -Xmx2g \
-XX:MaxGCPauseMillis=200 \
-Xlog:gc*:file=/var/log/gc.log \
-jar ilic.jar
โ ๊ธฐ๋ณธ G1 ์ฌ์ฉ. ๋ช
์์ UseG1GC ์ต์
๋ถํ์.
์ ์ง์ฐ ํ์ ์:
# Java 17+ ์ ZGC
java \
-XX:+UseZGC \
-Xms8g -Xmx8g \
-Xlog:gc*:file=/var/log/gc.log \
-jar ilic.jar
Java 21 ์ด์:
# Generational ZGC (๋ ํจ์จ์ )
java \
-XX:+UseZGC \
-XX:+ZGenerational \
-Xms8g -Xmx8g \
-jar ilic.jar
# 1. JConsole
jconsole <pid>
# 2. VisualVM
visualvm
# 3. JFR (Java Flight Recorder)
java -XX:StartFlightRecording=duration=60s,filename=recording.jfr -jar app.jar
# 4. JMC (Java Mission Control) ๋ก ๋ถ์
jmc
# 5. GC ๋ก๊ทธ ๋ถ์ ๋๊ตฌ
# - GCViewer (์คํ์์ค)
# - gceasy.io (์น ์๋น์ค)
java -jar myapp.jar # ๋ฌด์กฐ๊ฑด ๊ธฐ๋ณธ
๋ฌธ์ :
๊ถ์ฅ: ์ํฉ์ ๋ง๋ GC ๋ช ์์ ์ ํ.
java -XX:+UseConcMarkSweepGC -jar app.jar # โ Java 14+์์ ์ ๊ฑฐ
๋์ฒด:
"์ ์ง์ฐ = ZGC = ์ข๋ค"
์ง์ค:
์์น: Heap ํฌ๊ธฐ + ์ฐ์ ์์ ์ ๋ง๊ฒ.
java -Xmx8g -jar myapp.jar
๋๋ฝ:
-Xms (์ด๊ธฐ Heap) โ ์ด๊ธฐ ์์ผ๋ฉด ๋์ ํ์ฅ ๋น์ฉ-Xlog:gc (๋ก๊ทธ) โ ๋ถ์ ๋ถ๊ฐ-XX:+HeapDumpOnOutOfMemoryError โ ์ฌ๊ณ ์ ๋คํ X๊ถ์ฅ ์ต์ ์ต์ :
java -Xms4g -Xmx4g \
-Xlog:gc*:file=/var/log/gc.log \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/ \
-jar myapp.jar
java -Xms512m -Xmx4g -jar myapp.jar
๋ฌธ์ :
๊ถ์ฅ: Xms == Xmx (๋์ผ ๊ฐ)
java -Xms4g -Xmx4g -jar myapp.jar
์ด์ ํ๊ฒฝ:
ํด๊ฒฐ: ํญ์ GC ๋ก๊ทธ ํ์ฑํ.
java -XX:+UseG1GC -XX:G1HeapRegionSize=64m -Xmx2g -jar app.jar
๋ฌธ์ :
๊ถ์ฅ: G1 ์๋ ๊ณ์ฐ ์ฌ์ฉ (์ต์ ์๋ต).
[Unit 5.1: GC ๊ธฐ๋ณธ + ์ฝํ ์ธ๋ ๊ฐ์ค] โ
โ
[Unit 5.2: Heap ์ ์ธ๋ ๊ตฌ์กฐ] โ
โ
[Unit 5.3: GC ์๊ณ ๋ฆฌ์ฆ 4๊ฐ์ง] โ
โ
[Unit 5.4: GC ์ข
๋ฅ์ ์ ํ ๊ธฐ์ค] โ ์ง๊ธ ์ฌ๊ธฐ โ
โ
[Phase 5 ์๋ฃ!] ๐
โ Phase 5 ์๋ฃ. ๋ค์์ Phase 6 ๋ฐ์ดํฐ ๋ค๋ฃจ๊ธฐ.
| ํ์ต | GC ์ ํ ๊ด์ |
|---|---|
| Unit 4.1 (Heap ์์ญ) | GC ์ ๋ฌด๋ |
| Unit 4.2 (Pass by Value) | ๊ฐ์ฒด ์ฐธ์กฐ โ GC ์ํฅ |
| Unit 5.1 (์ฝํ ์ธ๋) | Generational ์ ๊ธฐ๋ฐ |
| Unit 5.2 (์ธ๋ ๊ตฌ์กฐ) | G1 ์ Region ์ดํด |
| Unit 5.3 (์๊ณ ๋ฆฌ์ฆ) | GC ์ข ๋ฅ์ ํ ๋ |
4์ฃผ์ฐจ (๋์์ฑ):
5์ฃผ์ฐจ (Spring DI):
11-12์ฃผ์ฐจ (JPA):
13-14์ฃผ์ฐจ (DB/Cache):
17์ฃผ์ฐจ (MSA):
19์ฃผ์ฐจ (ํ ์คํธ):
์ ILIC ์๋น์ค ์์
โ
Java ๋ฒ์ ?
โโโ 8: Parallel ๊ธฐ๋ณธ (๋ณ๊ฒฝ ๊ถ์ฅ โ G1)
โโโ 11+: G1 ๊ธฐ๋ณธ (๋๋ถ๋ถ ๊ทธ๋๋ก)
โ
์๋ต ์๊ฐ SLA?
โโโ 1์ด+ OK: G1 (๊ธฐ๋ณธ)
โโโ 200ms ๋ชฉํ: G1 + MaxGCPauseMillis=200
โโโ 100ms ๋ฏธ๋ง: ZGC ๊ณ ๋ ค
โ
Heap ํฌ๊ธฐ?
โโโ ~4GB: G1
โโโ 4~32GB: G1 (ํ๋ ๊ฐ๋ฅ)
โโโ 32GB+: ZGC ๊ฐ๋ ฅ ๊ถ์ฅ
โ
Java 21+?
โโโ ZGC ์ฌ์ฉ ์ +ZGenerational
| ์ง๋ฌธ | ์ด Unit์์์ ๋ต |
|---|---|
| "GC ์ข ๋ฅ?" | Serial, Parallel, CMS (deprecated), G1, ZGC, Shenandoah |
| "Java 8/9 ๊ธฐ๋ณธ GC ๋ณํ?" | Parallel โ G1 |
| "G1 vs ZGC?" | G1 = ๊ท ํ, ZGC = ์ ์ง์ฐ |
| "ILIC ์์ ์ด๋ค GC?" | "G1 ์ฌ์ฉํ๊ณ , MaxGCPauseMillis=200" |
| "CMS ๊ฐ deprecated ๋ ์ด์ ?" | ๋จํธํ + ๋ณต์ก์ฑ |
1๏ธโฃ ์๋ฐ GC ๋ 6๊ฐ์ง โ Serial, Parallel, CMS (deprecated), G1, ZGC, Shenandoah.
Serial = ๋จ์ผ ์ค๋ ๋ (์์ ํ๊ฒฝ), Parallel = ๋ฉํฐ ์ค๋ ๋ (Java 8 ๊ธฐ๋ณธ, ์ฒ๋ฆฌ๋), CMS = Concurrent (Java 14์์ ์ ๊ฑฐ), G1 = Region ๊ธฐ๋ฐ (Java 9+ ๊ธฐ๋ณธ, ์ผ๋ฐ ๋ฐฑ์๋), ZGC = Colored Pointer (์ ์ง์ฐ, ํฐ Heap), Shenandoah = Red Hat ์ ZGC ์ ์ฌํ. ๋ชจ๋ Generational + ์ถ๊ฐ ์ต์ ํ.
2๏ธโฃ G1 ์ ์ผ๋ฐ ๋ฐฑ์๋์ ํ์ค, ZGC ๋ ์ ์ง์ฐ์ ๋ต.
G1 ์ Region ๊ธฐ๋ฐ + Garbage First ์ ๋ต์ผ๋ก ๋ชฉํ STW ์ค์ (
MaxGCPauseMillis=200) ๊ฐ๋ฅ. ํฐ Heap ์์๋ ํจ์จ์ . ZGC ์ Colored Pointer + Load Barrier ๋ก STW 10ms ์ดํ (Heap ํฌ๊ธฐ ๋ฌด๊ด). ์๋ต์ฑ vs ์ฒ๋ฆฌ๋/๋ฉ๋ชจ๋ฆฌ์ trade-off โ ๋ฐ์น์ ๋์ Java 17 + ILIC 4GB Heap ํ๊ฒฝ์ด๋ผ๋ฉด G1 ์ด ์ ๋ต.3๏ธโฃ GC ์ ํ์ Heap ํฌ๊ธฐ + ์ฐ์ ์์์ ๋ต์ด๋ค.
~100MB โ Serial, ~4GB โ G1 (๋๋ ์ฒ๋ฆฌ๋ ์ฐ์ ์ด๋ฉด Parallel), 4~32GB โ G1, 32GB+ ๋๋ ์ ์ง์ฐ โ ZGC. ์ด์ ์ ํญ์ GC ๋ก๊ทธ ํ์ฑํ + HeapDumpOnOutOfMemoryError + Xms=Xmx ๊ถ์ฅ. Java 14+ ์์ CMS ์ฌ์ฉ ์๋๋ X. ์ด๋ฐ ๋ช ํํ ๊ธฐ์ค์ผ๋ก GC ์ ํํ ์ ์์ด์ผ ์๋์ด ์๋ฐ ๊ฐ๋ฐ์.
Q1: G1 GC ๊ฐ ํฐ Heap ์ ์ ํฉํ ์ด์ ๋?
ํ ์ค ๋ต: Region ๊ธฐ๋ฐ + Garbage First ์ ๋ต + ๋ชฉํ STW ์ค์ ๊ฐ๋ฅ ์ผ๋ก ํฐ Heap ์์๋ STW ์งง๊ฒ ์ ์ง.
์์ธ ์ค๋ช :
๊ธฐ์กด (Parallel, Serial) GC:
[Heap 16GB]
โโโ Young (5GB)
โโโ Old (11GB)
Old GC (Major GC) ์:
ํฐ Heap = ๊ธด STW โ ๏ธ.
[Heap 16GB]
โโโ Region 0 (4MB)
โโโ Region 1 (4MB)
โโโ Region 2 (4MB)
โโโ ... 4000๊ฐ Region
โโโ Region 3999
Region ์ ์๋ฏธ:
GC ์ ๊ฒฐ์ :
"์ด๋ค Region ๋ถํฐ ์ฒญ์ํ ๊น?"
๊ฐ Region ์ Garbage ๋น์จ ๋ถ์:
- Region A: 80% Garbage
- Region B: 20% Garbage
- Region C: 90% Garbage
- Region D: 10% Garbage
์ ํ: ํจ์จ ๋์ ์์
- Region C (90%)
- Region A (80%)
- Region B (20%) โ ํจ์จ ๋ฎ์ โ ์คํต
ํจ๊ณผ:
-XX:MaxGCPauseMillis=200 # ๋ชฉํ STW 200ms
G1 ์ ๋์:
1. 200ms ์์ ๋๋ผ ์ ์๋ Region ์ ๊ณ์ฐ
2. ๊ทธ๋งํผ๋ง ์ฒญ์
3. ๋ค์ GC ์์ ๋๋จธ์ง ์ฒ๋ฆฌ
์์:
โ ํญ์ 200ms ์์ GC ์๋ฃ.
G1 ์ ์ผ๋ถ ์์ ์ Application Thread ์ ๋์ ์คํ:
1. Initial Mark (STW, ์งง์)
2. Concurrent Mark (Application ๊ณผ ๋์) โญ
3. Remark (STW, ์งง์)
4. Cleanup (Concurrent + ์งง์ STW)
5. Mixed GC (Young + ์ผ๋ถ Old)
ํจ๊ณผ:
Heap 16GB, Old ๊ฐ๋:
Parallel GC:
Full GC:
- 16GB ์ ์ฒด ๋งํน (์ ์ด)
- ์์ถ (์ ์ด)
- ์ด STW: 5~10์ด โ ๏ธ
G1 GC:
Mixed GC:
- Concurrent Mark (์ ์ด, ๋์ ์คํ)
- 200ms ๋งํผ Region ์ฒญ์
- ๋ถ์กฑํ๋ฉด ๋ค์ GC ์์ ๋
- ์ด STW: 200ms โ
โ ํฐ Heap ์ผ์๋ก G1 ์ ํจ๊ณผ โ.
G1 ๋ง์ ํน์ ์ฒ๋ฆฌ:
"G1 ์ Region ๊ธฐ๋ฐ ์ค๊ณ์ Garbage First ์ ๋ต์ด ํฐ Heap ์์ STW ๋ฅผ ์งง๊ฒ ์ ์ง.
Concurrent Marking ์ผ๋ก Application ๊ณผ ๋์ ์์ + ๋ชฉํ STW ์ค์ ์ผ๋ก ์๋ต์ฑ ๋ณด์ฅ.
๊ทธ๋์ 4GB ์ด์ ํฐ Heap ์ ์ ํฉ."
Q2: ZGC ์ G1 ์ ๊ฐ์ฅ ํฐ ์ฐจ์ด๋?
ํ ์ค ๋ต: STW ๊ธธ์ด์ ์ฐจ์์ด ๋ค๋ฆ โ G1 ~200ms vs ZGC ~10ms ์ดํ.
์์ธ ๋น๊ต:
| G1 | ZGC | |
|---|---|---|
| ๋ชฉํ STW | ~200ms | ~10ms ์ดํ |
| Heap ํฌ๊ธฐ์ ๊ด๊ณ | ์ด๋ ์ ๋ ๋น๋ก | ๋ฌด๊ด |
| ํฐ Heap ์์ | STW ๊ธธ์ด์ง | STW ๊ทธ๋๋ก |
ZGC ์ ๋ง๋ฒ โ Heap ์ด 100GB ๋ 1TB ๋ STW ๋์ผ (~10ms).
G1:
ZGC:
| G1 | ZGC | |
|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋ | ๋ณดํต | ์ฝ๊ฐ โ |
| CPU ์ฌ์ฉ | ๋ณดํต | ์ฝ๊ฐ โ |
| ์ฒ๋ฆฌ๋ | ๋์ | ์ฝ๊ฐ โ |
โ ZGC ๋ ์๋ต์ฑ์ ์ํด ๋ค๋ฅธ ์์ ๋ ์ฌ์ฉ.
G1:
ZGC:
G1:
ZGC:
G1 ์ ์์ญ:
ZGC ์ ์์ญ:
G1 = ์ ๊ธฐ ์ฒญ์:
ZGC = 24์๊ฐ ์ฒญ์๋ถ:
Case 1: ์ผ๋ฐ ILIC API (Heap 4GB):
G1 โญ
- ์ถฉ๋ถํ ์๋ต์ฑ (200ms)
- ๋จ์ํ ์ด์
- Java 17 ๊ธฐ๋ณธ
Case 2: ILIC ์ค์๊ฐ ์๋ฆผ (Heap 8GB):
G1 ๊ฐ๋ฅ, ZGC ๋ OK
- G1 + MaxGCPauseMillis=100 ์๋
- ๋ถ์กฑํ๋ฉด ZGC ์ ํ
Case 3: ILIC ๋์ฉ๋ ๋ฐ์ดํฐ ๋ถ์ (Heap 64GB):
ZGC โญ
- ํฐ Heap ์์ STW ์์
- ์ฒ๋ฆฌ๋ ์ฝ๊ฐ ์์ค OK
"G1 = ์ผ๋ฐ ๋ฐฑ์๋์ ๊ท ํ (์๋ต์ฑ + ์ฒ๋ฆฌ๋),
ZGC = ์ ์ง์ฐ ์์คํ ์ ๋ต (์๋ต์ฑ ์ต์ฐ์ ).
์ฐจ์ด๋ STW ์ ์ฐจ์ ๊ณผ Heap ํฌ๊ธฐ ์์กด์ฑ.
ILIC ๊ฐ์ ์ผ๋ฐ ๋ฐฑ์๋๋ G1 ๊ฐ ์ ๋ต, ์ ์ง์ฐ ํ์ ์ ZGC ๊ฒํ ."
| Unit | ์ฃผ์ | ํต์ฌ |
|---|---|---|
| 5.1 | GC ๊ธฐ๋ณธ + ์ฝํ ์ธ๋ ๊ฐ์ค โ โ โ | Reachability, GC Root, STW |
| 5.2 | Heap ์ ์ธ๋ ๊ตฌ์กฐ โ โ โ | Eden/Survivor/Old, Promotion |
| 5.3 | GC ์๊ณ ๋ฆฌ์ฆ 4๊ฐ์ง | RC, Mark-Sweep, MSC, Generational |
| 5.4 | GC ์ข ๋ฅ์ ์ ํ ๊ธฐ์ค โ โ โ | Serial/Parallel/G1/ZGC |
"GC ๋ ์๋ฐ์ ์ ์๋ค. ์ธ๋ ๊ฐ์ค โ ์ธ๋ ๊ตฌ์กฐ โ ์๊ณ ๋ฆฌ์ฆ โ ์ข ๋ฅ โ ์ ํ โ ๋ชจ๋ ํ ํ๋ฆ."
์ฝํ ์ธ๋ ๊ฐ์ค์ด๋ผ๋ ํต์ฐฐ์ด Heap ์ ์ธ๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๊ณ , ์์ญ๋ง๋ค ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ๊ณ , ๊ฐ ํ๊ฒฝ์ ๋ง๋ GC ์ข ๋ฅ๋ก ์งํ. Phase 4 + Phase 5 ๊ฐ ์๋ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ์์ ํ ์ดํด.
๋ค์์ ์๋ฐ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ:
โ ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ (Phase 4-5) ์ดํด ์์์ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ค๋ฃธ.