Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Vai trò của String.intern() trong Java – String Pool

String.intern() trả về tham chiếu đến instance trong String Pool (chuỗi nội bộ). Giúp tiết kiệm bộ nhớ khi nhiều chuỗi trùng lặp.

Cơ chế String Pool

  • String literal ("abc") tự động vào pool
  • new String("abc") tạo object mới trên heap, KHÔNG vào pool
  • intern(): nếu pool đã có chuỗi bằng equals(), trả về reference pool; ngược lại thêm vào pool và trả về reference mới

Ví dụ minh họa


public class InternDemo {
    public static void main(String[] args) {
        String s1 = new String("Hello"); // heap object
        String s2 = "Hello";             // pool object
        String s3 = new String("Hello"); // heap object khác
        
        System.out.println("s1 == s2: " + (s1 == s2)); // false (khác object)
        System.out.println("s1.equals(s2): " + s1.equals(s2)); // true
        
        // Sau intern()
        String i1 = s1.intern(); // trả về pool reference (s2)
        String i2 = s2.intern(); // trả về pool reference (s2)
        String i3 = s3.intern(); // trả về pool reference (s2)
        
        System.out.println("i1 == i2: " + (i1 == i2)); // true
        System.out.println("i1 == s2: " + (i1 == s2)); // true
        System.out.println("i3 == s2: " + (i3 == s2)); // true
    }
}

Kết quả


s1 == s2: false
s1.equals(s2): true
i1 == i2: true
i1 == s2: true
i3 == s2: true

Khi nào dùng intern()?

  • Nhiều chuỗi trùng lặp (ví dụ: đọc file log, tên thành phố, từ điển)
  • So sánh bằng == thay vì equals() (nhanh hơn, nhưng nguy hiểm nếu quên intern)
  • Giảm memory footprint

⚠️ Cảnh báo

  • Java 7+: String pool chuyển từ PermGen (fixed size) sang Heap – an toàn hơn nhưng vẫn có overhead
  • Lạm dụng intern() → pool quá lớn → GC chậm, thậm chí OOM
  • Không dùng intern() cho input user không tin cậy (DoS vector)
  • So sánh chuỗi: luôn dùng equals(), chỉ dùng == khi chắc chắn đã intern()

Alternatives hiện đại

  • Dùng StringBuilder build chuỗi, không cần intern
  • Dùng Map<String, String> cache thủ công (weak reference)
  • JVM option: -XX:StringTableSize=N tùy chỉnh pool size