intern() tra chuỗi trong string pool: nếu pool đã có chuỗi bằng nội dung thì trả về tham chiếu trong pool, chưa có thì thêm vào rồi trả về.
Mục đích là để nhiều biến cùng nội dung chia sẻ một object.
String a = "hello"; // literal - vào pool lúc class được load
String b = new String("hello"); // object mới trên heap
System.out.println(a == b); // false
System.out.println(a == b.intern()); // trueLịch sử vị trí của pool:
- Java 6 trở về trước: pool nằm trong PermGen — vùng có kích thước cố định (-XX:MaxPermSize). Gọi intern() trên dữ liệu người dùng dễ gây OutOfMemoryError: PermGen space, và chuỗi trong pool gần như không được thu hồi.
- Java 7: pool được chuyển sang heap chính (RFE 6962931). Từ đây chuỗi interned chịu GC bình thường và không còn bị giới hạn PermGen.
- Java 8: PermGen bị bỏ hẳn, metadata class chuyển sang Metaspace; pool vẫn ở heap.
Lưu ý khi vận hành: pool được cài bằng một hash table kích thước cố định, chỉnh bằng -XX:StringTableSize; intern hàng triệu chuỗi khác nhau làm chuỗi va chạm dài ra và intern() chậm dần. Có thể đo bằng -XX:+PrintStringTableStatistics.
Thực tế hiếm khi cần gọi intern() thủ công. Muốn giảm bộ nhớ do chuỗi trùng lặp, bật -XX:+UseStringDeduplication (G1) để GC tự gộp mảng ký tự giống nhau mà không đụng vào string pool.