Trong Java, các loại reference (tham chiếu) đóng vai trò quan trọng trong quản lý bộ nhớ, đặc biệt là trong cách xử lý các đối tượng khi xảy ra quá trình thu gom rác (Garbage Collection). Trong đó, Soft ReferenceWeak Reference là hai loại tham chiếu yếu (non-strong references), mỗi loại có mục đích và cách hoạt động riêng khi Java quản lý bộ nhớ. Dưới đây là sự khác biệt chi tiết giữa chúng.

1. Soft Reference (Tham chiếu mềm)

Định nghĩa:

  • Soft Reference là loại tham chiếu mà Garbage Collector sẽ chỉ thu gom đối tượng được tham chiếu khi JVM thực sự cần thêm bộ nhớ (khi bộ nhớ sắp cạn kiệt).

Cách hoạt động:

  • Các đối tượng được tham chiếu bởi Soft Reference sẽ không bị thu gom ngay lập tức. Chúng chỉ bị xóa khi hệ thống đang thiếu bộ nhớ. Điều này làm cho Soft Reference rất hữu ích khi bạn muốn giữ các đối tượng trong bộ nhớ lâu hơn nhưng sẵn sàng giải phóng khi cần thiết.

Ứng dụng:

  • Soft Reference thường được sử dụng cho các cache (bộ nhớ tạm), nơi bạn muốn lưu trữ các đối tượng lâu nhất có thể, nhưng sẵn sàng giải phóng chúng khi hệ thống cần thêm bộ nhớ.

Cú pháp:

SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get(); // Truy xuất đối tượng từ Soft Reference

Đặc điểm:

  • Đối tượng được giữ bởi Soft Reference sẽ không bị thu gom cho đến khi JVM thực sự cần thêm bộ nhớ.
  • Soft Reference thường dùng cho các đối tượng lớn, không cần thiết phải giữ liên tục, nhưng vẫn có thể hữu ích nếu JVM có đủ bộ nhớ.
  • Khi hệ thống hết bộ nhớ, các đối tượng này sẽ bị thu gom rác.

2. Weak Reference (Tham chiếu yếu)

Định nghĩa:

  • Weak Reference là loại tham chiếu yếu hơn Soft Reference, và các đối tượng được tham chiếu bởi Weak Reference sẽ bị thu gom ngay lập tức trong lần thu gom rác tiếp theo, bất kể bộ nhớ của hệ thống có đủ hay không.

Cách hoạt động:

  • Khi một đối tượng chỉ còn được tham chiếu bởi Weak Reference và không có bất kỳ Strong Reference nào khác, Garbage Collector sẽ thu gom đối tượng đó mà không cần quan tâm đến trạng thái bộ nhớ của hệ thống.

Ứng dụng:

  • Weak Reference thường được sử dụng cho các cấu trúc dữ liệu như WeakHashMap, nơi bạn không muốn giữ đối tượng trong bộ nhớ khi không còn ai tham chiếu đến chúng.

Cú pháp:

WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get(); // Truy xuất đối tượng từ Weak Reference

Đặc điểm:

  • Đối tượng được giữ bởi Weak Reference sẽ bị thu gom rác ngay khi không có bất kỳ Strong Reference nào khác tham chiếu đến nó.
  • Weak Reference thường được sử dụng khi bạn muốn một đối tượng chỉ tồn tại khi có Strong Reference giữ nó. Khi không còn Strong Reference, đối tượng sẽ bị thu gom ngay lập tức.

3. So sánh giữa Soft Reference và Weak Reference

Tiêu chíSoft ReferenceWeak Reference
Mức độ ưu tiên thu gom rácThu gom khi JVM thiếu bộ nhớ.Thu gom ngay lập tức trong lần thu gom rác tiếp theo, bất kể bộ nhớ.
Thời gian tồn tại của đối tượngĐối tượng có thể tồn tại lâu hơn, chỉ bị thu gom khi thiếu bộ nhớ.Đối tượng sẽ bị thu gom ngay khi không có Strong Reference nào.
Ứng dụng phổ biếnThường dùng cho các bộ nhớ cache, lưu giữ dữ liệu tạm thời.Thường dùng trong các cấu trúc dữ liệu như WeakHashMap.
Ví dụ sử dụngCache các đối tượng lớn mà không cần giữ liên tục.Không giữ đối tượng khi không còn tham chiếu mạnh, ví dụ như WeakHashMap.

4. Ví dụ về SoftReferenceWeakReference

Ví dụ về SoftReference (Cache)

import java.lang.ref.SoftReference;

public class SoftReferenceExample {
    public static void main(String[] args) {
        SoftReference<byte[]> softCache = new SoftReference<>(new byte[1024 * 1024 * 10]); // 10 MB
        
        if (softCache.get() != null) {
            System.out.println("Cache is still available.");
        } else {
            System.out.println("Cache has been cleared by GC.");
        }
    }
}

Trong ví dụ này, nếu bộ nhớ hệ thống đủ, đối tượng sẽ được giữ lại và không bị thu gom. Tuy nhiên, nếu JVM thiếu bộ nhớ, đối tượng này sẽ bị thu gom để giải phóng không gian.

Ví dụ về WeakReference (WeakHashMap)

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.WeakHashMap;

public class WeakReferenceExample {
    public static void main(String[] args) {
        WeakReference<String> weakRef = new WeakReference<>(new String("Weak Reference Example"));
        
        System.out.println("Before GC: " + weakRef.get());
        
        System.gc();  // Kích hoạt thu gom rác
        
        System.out.println("After GC: " + weakRef.get());
    }
}

Trong ví dụ trên, sau khi thu gom rác, đối tượng được tham chiếu bởi weakRef sẽ bị thu gom ngay lập tức, và giá trị của weakRef.get() sẽ là null.

5. Kết luận

  • Soft ReferenceWeak Reference cung cấp cơ chế để quản lý bộ nhớ một cách hiệu quả hơn trong Java.
  • Soft Reference giữ đối tượng lâu hơn, chỉ thu gom khi JVM thiếu bộ nhớ, trong khi Weak Reference thu gom đối tượng ngay khi không còn Strong Reference nào.
  • Việc sử dụng các loại tham chiếu này giúp lập trình viên kiểm soát tốt hơn việc sử dụng bộ nhớ trong các ứng dụng yêu cầu quản lý bộ nhớ phức tạp như hệ thống cache hoặc cấu trúc dữ liệu không giữ các đối tượng một cách không cần thiết.