1. Định nghĩa:
Garbage Collection(GC) trong Java là cơ chế tự động thu hồi bộ nhớ heap, giúp xoá bỏ các object không còn sử dụng(không còn được tham chiếu) để giải phòng tài nguyên và tránh rò rỉ bộ nhớ.
2. GC hoạt động theo vùng bộ nhớ(Heap Memory):
Java Heap chia thành 3 vùng chính:
| Vùng | Mô tả |
|---|---|
| Young Generation | Nơi tạo object mới, chết nhanh |
| Old Generation | Object sống lâu, ít thay đổi |
| Metaspace | Lưu thông tin class, method (không phải object dữ liệu) |
3. Các bước hoạt động của GC:
Bước 1: Đánh dấu (Mark phase)
- JVM sẽ tìm tất cả các object còn đang được sử dụng (reachable).
- Dựa vào các root reference như:
- Biến static
- Biến trong stack (method đang chạy)
- Tham chiếu trong CPU register
- Những object có thể đi đến từ root sẽ được đánh dấu là “còn sống”.
👉 Tưởng tượng như: GC đi theo dây dẫn điện để biết bóng đèn nào còn sáng → đèn còn sáng = còn dùng.
Bước 2: Dọn dẹp (Sweep phase)
- Các object không được đánh dấu sẽ bị coi là “rác” → GC xóa khỏi bộ nhớ heap.
- Vùng nhớ của các object này được giải phóng.
👉 Như người dọn rác gom bỏ những món đồ không còn ai đụng tới.
Bước 3(Tuỳ chọn): Nén bộ nhớ (Compact phase)
- Sau khi xóa rác, vùng heap có thể bị phân mảnh (nhiều khoảng trống rải rác).
- JVM có thể gom các object còn lại về một chỗ, làm liên tục vùng nhớ, giúp cấp phát mới dễ hơn.
👉 Như bạn dọn tủ quần áo, gom đồ gọn lại một góc để trống phía còn lại.
4. Các loại GC phổ biến trong JVM:
| Loại GC | Ưu điểm | Nhược điểm | Dùng khi |
|---|---|---|---|
| Serial GC | Đơn giản, dùng ít CPU | Dừng toàn bộ app trong lúc chạy | App nhỏ |
| Parallel GC | Nhanh, đa luồng | Tạm dừng app ngắn | App vừa |
| CMS GC | Giảm độ trễ (pause time) | Cấu hình phức tạp, tốn CPU | App real-time |
| G1 GC | Cân bằng hiệu năng & độ trễ | Phức tạp, nhiều tham số | App lớn, Java 9+ mặc định |
5. Một số hiểu nhầm thường gặp:
| Hiểu sai | Thực tế là… |
|---|---|
System.gc() sẽ dọn ngay | Không chắc chắn – chỉ là gợi ý cho JVM |
| GC luôn tốt | Nếu cấu hình sai → pause lâu, chậm app |
| Object bị null = xóa ngay | Chưa chắc – chỉ đủ điều kiện để xóa |
6. Cách kiểm tra GC hoạt động:
Chọn loại Garbage Collector:
| GC | JVM Option |
|---|---|
| Serial GC | -XX:+UseSerialGC |
| Parallel GC | -XX:+UseParallelGC (mặc định Java 8) |
| CMS GC | -XX:+UseConcMarkSweepGC (deprecated từ Java 9) |
| G1 GC | -XX:+UseG1GC (mặc định Java 9+) |
| ZGC | -XX:+UseZGC (Java 11+) |
| Shenandoah GC | -XX:+UseShenandoahGC (Java 12+) |
Cấu hình Heap Memory:
| Mục đích | JVM Option | Description |
|---|---|---|
| Kích thước heap ban đầu | -Xms<size> | Ví dụ: -Xms512m |
| Kích thước heap tối đa | -Xmx<size> | Ví dụ: -Xmx2g |
| Tỉ lệ giữa Old/Young Generation | -XX:NewRatio=2 | Young = 1 phần, Old = 2 phần |
| Tỉ lệ vùng Survivor | -XX:SurvivorRatio=6 | Tỉ lệ Eden:Survivor:Survivor = 6:1:1 |
7. Lợi ích của GC:
Nó làm cho bộ nhớ Java hiệu quả vì bộ thu rác sẽ loại bỏ các đối tượng không được chấp thuận khỏi bộ nhớ heap.
Nó được tự động thực hiện bởi người thu gom rác (một phần của JVM), vì vậy chúng tôi không cần nỗ lực thêm.
Bổ sung: Ba trạng thái trong GC:
1️⃣ Reachable (Có thể truy cập)
- Định nghĩa: Object còn được tham chiếu trực tiếp hoặc gián tiếp từ GC roots (ví dụ: biến cục bộ đang chạy trên stack, biến static, thread đang hoạt động).
- Ý nghĩa:
- JVM không thể thu gom object này.
- Bạn vẫn có thể dùng object bình thường.
- Ví dụ:
Object a = new Object(); // a là GC root reference
Object b = a; // b tham chiếu a -> reachable
2️⃣ Finalizable (Chờ finalize)
- Định nghĩa: Object không còn reachable, nhưng override phương thức
finalize()(hoặc kế thừa từ class đã override). - Quy trình:
- GC phát hiện object unreachable nhưng có
finalize(). - GC đặt vào hàng đợi finalization thay vì thu gom ngay.
- Thread finalizer sẽ gọi
finalize()một lần duy nhất. - Nếu trong
finalize()object gán lại tham chiếu của mình cho một biến reachable → object “hồi sinh”(resurrected) và trở lại trạng thái reachable. - Nếu không được hồi sinh, lần kế tiếp GC sẽ thấy nó unreachable và thu gom.
- GC phát hiện object unreachable nhưng có
- Ví dụ:
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize called");
}
3️⃣ Unreachable (Không thể truy cập)
- Định nghĩa: Không còn đường dẫn nào từ GC roots tới object.
- Ý nghĩa:
- Object này sẽ bị thu gom ở lần GC kế tiếp.
- Nếu đã finalizable và đã gọi
finalize()trước đó, GC sẽ thu gom vĩnh viễn.
- Ví dụ:
Object x = new Object();
x = null; // Không còn tham chiếu tới object -> unreachable
📊 Sơ đồ tóm tắt luồng trạng thái
Reachable
|
| (Mất hết tham chiếu)
v
Unreachable ---> [Nếu có finalize()] ---> Finalizable Queue
|
v
Finalize() chạy
|
(Được hồi sinh?) --yes--> Reachable
|
no
v
Thu gom rác
Reference:
Be First to Comment