String Interning & String Pool: Tối ưu Memory trong Production
1. Mở Đầu: Bài Toán Bộ Nhớ Trong các hệ thống Java Enterprise quy mô lớn, khi thực hiện profiling bộ nhớ (Heap Dump Analysis) bằng các công cụ chuyên dụng như Eclipse MAT, VisualVM hay Profiler, một kịch bản rất phổ biến xuất hiện: đối tượng java.lang.String (cùng mảng dữ liệu byte[]/char[] đi kèm) thường chiếm tới 25% – 30%, đôi khi vượt ngưỡng 40% tổng dung lượng Java Heap. Nguyên nhân chính không nằm ở bản thân mã nguồn ứng dụng tạo quá nhiều biến chuỗi cố định, mà xuất phát từ dữ liệu động được nạp liên tục ở runtime qua các thao tác I/O: Đọc các bản ghi từ Database (các giá trị cột như status, type, country_code lặp đi lặp lại hàng triệu lần). Deserialization dữ liệu từ REST API, gRPC responses, Message Queue (Kafka, RabbitMQ) chứa cùng các JSON keys. Đọc file log, file cấu hình CSV/XML. Mặc dù các giá trị chuỗi này về mặt ngữ nghĩa hoàn toàn giống nhau (ví dụ: hàng triệu chuỗi “ACTIVE”), mặc định JVM vẫn khởi tạo từng instance String riêng biệt trên Java Heap cùng mảng bộ nhớ lưu...