
Written on 3rd September 2026 by Carter Phan.
Garbage Collection = JVM tự động tìm và giải phóng các object không còn reachable, giúp developer không phải tự free() memory.
Java Code
↓
new Object()
↓
Heap
↓
Object không còn reachable
↓
GC phát hiện
↓
Reclaim memory
Trong Java, object được tạo trên Heap:
Useruser=newUser();
Sau đó:
user=null;
Object User không còn reference nào tới nó.
Stack Heap
user ──────────────→ User Object
↓
user = null
user ─────────────X User Object
↓
unreachable
↓
GC
👉 Object vẫn tồn tại trong Heap cho đến khi GC reclaim memory.
Không đơn giản là:
"Object nào không có reference trực tiếp thì xóa."
Java sử dụng concept Reachability.
Một số object/reference được xem là GC Roots, ví dụ:
GC Root
│
▼
Object A
│
▼
Object B
Object C ──X──> không reachable
👉 A, B vẫn sống.
👉 C có thể được GC.
Một cách đơn giản hóa:
Mark
↓
Sweep
↓
Compact
Tìm tất cả object còn reachable.
A ✅
B ✅
C ❌
D ❌
Reclaim object không còn sử dụng.
A ✅
B ✅
C 🗑️
D 🗑️
Di chuyển object còn sống để giảm fragmentation.
Before:
[A][X][B][X][X][C]
After:
[A][B][C][ ]
⚠️ Không phải collector nào cũng thực hiện các bước này theo đúng cách hoặc trong một phase riêng biệt.
Một concept rất quan trọng khi interview:
Phần lớn object Java có lifetime ngắn.
Ví dụ:
publicResponsegetUser() {UserDtodto=newUserDto();returndto;
}
Nhiều temporary object chỉ tồn tại trong thời gian ngắn.
Vì vậy Heap thường được tổ chức theo generations:
Heap
│
├── Young Generation
│ ├── Eden
│ ├── Survivor
│ └── Survivor
│
└── Old Generation
Object mới:
new Object()
↓
Eden
Nếu sống qua một số GC cycles:
Eden
↓
Survivor
↓
Survivor
↓
Old Generation
Object càng sống lâu → khả năng được promote vào Old Generation càng cao.
Xảy ra chủ yếu ở Young Generation.
Eden
↓
Minor GC
↓
Dead objects → remove
Live objects → Survivor
Khi Old Generation cần reclaim memory, collector sẽ xử lý phần Old Gen.
Tùy GC implementation, terminology như Major GC / Full GC có ý nghĩa khác nhau, nên trong interview không nên đồng nhất chúng một cách tuyệt đối.
Một concept rất quan trọng.
Stop-The-World = application threads bị pause trong một số GC phases.
Application threads
██████████
⏸️ GC
⏸️
████████████████
Nếu GC pause quá lâu:
Request
↓
Thread waiting
↓
GC pause
↓
Latency ↑
↓
Timeout
👉 Production system quan tâm rất nhiều đến:
G1 (Garbage-First) là collector phổ biến trong các JVM hiện đại.
Heap được chia thành nhiều regions:
Heap
┌──┬──┬──┬──┬──┐
│E │O │E │S │O │
├──┼──┼──┼──┼──┤
│O │E │E │O │E │
└──┴──┴──┴──┴──┘
G1 ưu tiên những region có nhiều garbage để reclaim.
✅ Pause time có thể kiểm soát tốt hơn
✅ Phù hợp application có heap lớn
❌ Có overhead quản lý region / GC metadata
Collector tập trung mạnh vào low latency.
Mục tiêu:
Large Heap
+
Low GC Pause
Phù hợp với:
Tương tự ZGC ở mục tiêu:
Low pause time
Collector cố gắng thực hiện phần lớn công việc GC concurrently với application.
Application
↓
Stop
↓
1 GC thread
↓
Resume
Simple nhưng không phù hợp workload lớn/high-concurrency.
Dùng nhiều GC threads:
GC
├── Thread 1
├── Thread 2
├── Thread 3
└── Thread 4
👉 Ưu tiên throughput.
Không có GC nào:
"Tốt nhất cho mọi application."
Thường có trade-off:
| GC | Ưu tiên | Use case |
| Serial | Simplicity | Small app |
| Parallel | Throughput | Batch / CPU-heavy |
| G1 | Balanced / predictable pause | General server |
| ZGC | Low latency | Large heap / latency-sensitive |
| Shenandoah | Low latency | Latency-sensitive |
Một object có thể không còn cần thiết về mặt business nhưng vẫn reachable.
Ví dụ:
staticList<User>users=newArrayList<>();
Nếu cứ:
users.add(user);
mà không remove:
GC Root
↓
static users
↓
User
↓
User
↓
User
...
👉 GC không thể xóa vì objects vẫn reachable.
Đây là một dạng memory leak trong managed language.
staticMap<Long,User>cache;
Không cleanup.
Cache
↓
unlimited growth
Object
↓
Event Listener
↓
reference giữ object sống
Đặc biệt đáng chú ý trong thread pool.
malloc()
↓
use
↓
free() ← developer
new
↓
use
↓
unreachable
↓
GC
👉 GC giảm lỗi như:
Nếu Java service bị:
Latency ↑
CPU ↑
Memory ↑
Không nên kết luận ngay:
"GC bị lỗi."
Check:
Heap usage
GC frequency
GC pause time
Allocation rate
Old Gen usage
Live objects after GC
Nếu:
Heap ↑
↓
Full GC
↓
Heap vẫn ↑
↓
Live objects nhiều
👉 Có thể có memory leak hoặc workload thực sự cần nhiều memory.