Chuỗi ký tự không được lưu trữ trên ngăn xếp. Không bao giờ. Trên thực tế, không có đối tượng nào được lưu trữ trên ngăn xếp.
Xâu (hay chính xác hơn, các đối tượng chuỗi đại diện cho họ) đang được lưu trữ lịch sử trong một Heap gọi là "PermGen" heap. (Permgen là viết tắt của thế hệ vĩnh viễn.)
Trong các trường hợp bình thường, các chuỗi ký tự và nhiều nội dung khác trong heap permgen có thể truy cập "vĩnh viễn" và không được thu thập rác. (Ví dụ: các ký tự chuỗi luôn có thể truy cập được từ các đối tượng mã sử dụng chúng.) Tuy nhiên, bạn có thể định cấu hình JVM để cố gắng tìm và thu thập các lớp được tải động không còn cần thiết nữa và điều này có thể khiến các ký tự chuỗi bị thu thập rác .
XÁC NHẬN # 1 - Tôi không nói rằng Permgen không đạt được GC'ed. Điều này xảy ra, thường là khi JVM quyết định chạy một GC đầy đủ. Quan điểm của tôi là các chuỗi ký tự sẽ có thể truy cập được miễn là có thể truy cập được mã sử dụng chúng và mã sẽ có thể truy cập được miễn là có thể truy cập được trình tải lớp của mã và đối với trình tải lớp mặc định, điều đó có nghĩa là "mãi mãi".
XÁC NHẬN # 2 - Trên thực tế, Java 7 trở lên sử dụng heap thông thường để giữ nhóm chuỗi. Do đó, các đối tượng String đại diện cho các chuỗi ký tự String và chuỗi intern'd thực sự nằm trong heap thông thường. (Xem Câu trả lời của @ assylias để biết thêm chi tiết.)
Nhưng tôi vẫn đang cố gắng tìm ra ranh giới giữa lưu trữ chuỗi ký tự và chuỗi được tạo bằng new
.
Không có "đường mỏng". Cái này rất là đơn giản:
String
các đối tượng đại diện / tương ứng với các ký tự chuỗi được giữ trong nhóm chuỗi.
String
các đối tượng được tạo bởi một String::intern
cuộc gọi được giữ trong nhóm chuỗi.
- Tất cả các
String
đối tượng khác KHÔNG được giữ trong nhóm chuỗi.
Sau đó, có một câu hỏi riêng về nơi lưu trữ chuỗi ký tự. Trước Java 7, nó là heap permgen. Từ Java 7 trở đi, nó là đống chính.