Bộ nhớ Stack và Heap trong Java

Trong Java, quản lý bộ nhớ là một quá trình quan trọng. Nó được quản lý bởi Java một cách tự động. JVM chia bộ nhớ thành hai phần: bộ nhớ Stack và bộ nhớ Heap. Theo quan điểm của Java, cả hai đều là vùng bộ nhớ quan trọng nhưng cả hai đều được sử dụng cho các mục đích khác nhau. Sự khác biệt chính giữa bộ nhớ Stack và bộ nhớ heap là Stack được sử dụng để lưu trữ thứ tự thực thi phương thức và các biến cục bộ, trong khi bộ nhớ heap lưu trữ các đối tượng và nó sử dụng cấp phát và giải phóng bộ nhớ động. Trong phần này, chúng ta sẽ thảo luận chi tiết về sự khác biệt giữa stack và heap.

Bộ nhớ Stack

Bộ nhớ Stack là một không gian vật lý (trong RAM) được phân bổ cho từng luồng(thread) trong thời gian chạy. Nó được tạo ra khi một chủ đề tạo ra. Việc quản lý bộ nhớ Stack tuân theo thứ tự LIFO (Last-In-First-Out) vì nó có thể truy cập được phạm vi Global. Nó lưu trữ các biến, tham chiếu đến đối tượng và kết quả từng phần. Bộ nhớ được phân bổ cho Stack tồn tại cho đến khi hàm kết thú. Nếu không có không gian để tạo các đối tượng mới, nó sẽ thrown java.lang.StackOverFlowError. Phạm vi của các yếu tố được giới hạn trong chủ đề của họ. JVM tạo một Stack riêng cho mỗi thread.

Bộ nhớ Heap

Nó được tạo khi JVM khởi động và được ứng dụng sử dụng trong thời gian ứng dụng đang chạy. Nó lưu trữ các object và các class trong JRE. Bất cứ khi nào chúng ta tạo các object, nó sẽ chiếm không gian trong bộ nhớ heap trong khi tham chiếu của đối tượng đó tạo trong vùng nhớ Stack. Vùng nhớ Heap không tuân theo bất kỳ thứ tự nào như Stack. Nó tự động xử lý các khối bộ nhớ. Điều đó có nghĩa là chúng ta không cần xử lý bộ nhớ theo cách thủ công. Để quản lý bộ nhớ một cách tự động, Java cung cấp trình thu gom rác( the garbage collector) để xóa các object không còn được sử dụng. Bộ nhớ được phân bổ cho heap tồn tại cho đến khi bất kỳ một sự kiện nào, chương trình kết thúc hoặc không còn bộ nhớ trống. 

Các thành phần có thể truy cập trong toàn bộ ứng dụng. Đó là một không gian vùng nhớ chung được chia sẻ với tất cả các luồng thread. Nếu không gian heap đầy, nó sẽ throw java.lang.OutOfMemoryError.

 Bộ nhớ heap được chia thành các vùng bộ nhớ sau:

  • Young generation
  • Survivor space
  • Old generation
  • Permanent generation
  • Code Cache

(Chi tiết từng thành phần mình sẽ viết sau về bộ nhớ Heap ở bài riêng)

Hình ảnh sau đây cho thấy việc phân bổ bộ nhớ ngăn xếp và không gian heap.

Sự khác biệt giữa Bộ nhớ Stack và Bộ nhớ Heap

Tham sốStackHeap
Thành phần trong ứng dụngNó lưu trữ các mục có tuổi thọ rất ngắn như phương thức, biến và biến tham chiếu của đối tượng.Nó lưu trữ các đối tượng và các lớp Java Runtime Environment (JRE).
Thứ tựNó tuân theo thứ tự LIFO(Last Input First Outut) .Nó không tuân theo bất kỳ thứ tự nào vì nó là cấp phát bộ nhớ động và không có bất kỳ mẫu cố định nào để cấp phát và hủy cấp phát các khối bộ nhớ.
Tính Linh hoạtNó không linh hoạt vì chúng ta không thể thay đổi bộ nhớ được cấp phát.Nó linh hoạt vì chúng ta có thể thay đổi bộ nhớ được phân bổ.
Tính Hiệu quảNó có quyền truy cập, phân bổ và phân bổ nhanh hơn .Nó có quyền truy cập, phân bổ và phân bổ chậm hơn .
Kích thước bộ nhớNó có kích thước nhỏ hơn .Nó có kích thước lớn hơn .
Cấu hình trong JavaChúng ta có thể tăng kích thước dung lượng vùng nhớ Stack bằng cách sử dụng tùy chọn JVM -Xss.Chúng ta có thể tăng hoặc giảm kích thước vùng nhớ Heap bằng cách sử dụng các tùy chọn – Xmx và -Xms JVM.
Phạm vi truy cậpCác biến chỉ được truy cập trong luồng thread của chính nóCác biến được truy cập trong tất cả các thread khác.
Phân bổ không gian vùng nhớKhi một thread được khởi tạo, hệ điều hành sẽ tự động phân bổ vùng nhớ stack.Để tạo không gian heap cho ứng dụng, Java gọi đến hệ điều hành trong quá trình run time.
Phân bổStack riêng biệt được tạo cho từng thành phần.Nó được chia sẻ giữa tất cả các thread.
Exception JVM throw java.lang.StackOverFlowError nếu kích thước sử dụng vùng nhớ Stack lớn hơn giới hạn. Để tránh lỗi này, hãy tăng kích thước Stack.JVM throw java.lang.OutOfMemoryError nếu JVM không thể tạo một native method mới.
Phân bổ/Giải phòng bộ nhớNó được thực hiện tự động bởi trình biên dịch(compiler).Nó được thực hiện thủ công bởi lập trình viên(programmer).
Chi phíChi phí của nó là ít hơn .Chi phí của nó cao hơn so với Stack.
ImplementationThực hiện khó hơn.Thực hiện dễ dàng hơn.
Thứ tự phân bổCấp phát bộ nhớ là liên tục theo thứ tự.Bộ nhớ được phân bổ theo thứ tự ngẫu nhiên .
Khả năng an toànAn toàn cho thread vì mỗi luồng được phân bổ vùng nhớ stack riêng.Không an toàn cho thread, vì vậy dùng lệnh synchronization để đồng bộ.

Nguồn tham khảo:

https://www.javatpoint.com/stack-vs-heap-java

Related Posts
Lịch sử ngôn ngữ lập trình Java

Java (phiên âm Tiếng Việt: "Gia-va") là một ngôn ngữ lập trình hướng đối tượng, dựa trên lớp được thiết Read more

Phím tắt trong Eclipse giúp tăng năng suất coding

Các phím tắt sẽ giúp tốc độ coding của bạn nhanh hơn rất nhiều, hơn nữa format code của bạn Read more

Lập trình Hướng đối tượng(OOP)

Lập trình hướng đối tượng (tiếng Anh: Object-oriented programming, viết tắt: OOP) là một mẫu hình lập trình dựa trên Read more

Kiểu dữ liệu Nguyên thủy(Primitive)

1. Tổng quan Trong ngôn ngữ lập trình Java có 2 kiểu dữ liệu chúng ta cần nắm và phân Read more

Hãy bình luận đầu tiên

Để lại một phản hồi