Stack là vùng nhớ mỗi thread có riêng, lưu biến local và tham chiếu, tự giải phóng khi method kết thúc theo LIFO. Heap là vùng nhớ dùng chung cho toàn JVM, lưu object thật và được Garbage Collector dọn.
Hãy hình dung stack như một tờ giấy nháp bạn dùng trong một cuộc gọi: ghi nhanh, xoá ngay khi xong việc. Heap như một kho đồ dùng chung: mọi người đều lấy được, nhưng phải có người dọn dẹp định kỳ.
Cơ chế: Khi gọi method, JVM tạo một stack frame chứa biến local và tham chiếu. Khi method return, frame bị pop khỏi stack, dữ liệu trên stack biến mất ngay. Object tạo bằng new luôn nằm trên heap; nếu không còn tham chiếu nào trỏ tới, GC sẽ thu hồi sau. Vì stack chỉ dịch con trỏ nên nhanh, nhưng nhỏ và gắn với luồng thực thi; heap lớn hơn nhưng phải chịu chi phí GC.
void demo() {
int x = 5; // x nằm trên STACK
Person p = new Person(); // tham chiếu p ở stack, object Person ở HEAP
} // hết method: x + p rời stack, object chờ GCLỗi thường gặp:
- Đệ quy quá sâu → StackOverflowError vì stack đầy.
- Giữ quá nhiều object sống lâu → OutOfMemoryError: Java heap space.
- Hai biến cùng trỏ một object trên heap: sửa qua biến này, biến kia thấy thay đổi.
Lưu ý: Trong Java, primitive và reference nằm trên stack, còn object luôn nằm trên heap. "Java pass-by-value" nghĩa là copy giá trị tham chiếu, không copy object.