Đầu tiên, Sự khác biệt giữa không gian Perm và không gian Heap (JVM chọn sử dụng mỗi không gian bộ nhớ như thế nào và như thế nào)?
Thứ hai, nhưng quan trọng nhất, loại tỷ lệ nào sẽ được đề xuất cho một ứng dụng java loại MVC tiêu chuẩn?
Câu trả lời:
Các đống lưu trữ tất cả các đối tượng được tạo ra bởi chương trình Java của bạn. Nội dung của heap được giám sát bởi bộ thu gom rác, giúp giải phóng bộ nhớ khỏi heap khi bạn ngừng sử dụng một đối tượng (tức là khi không còn tham chiếu nào đến đối tượng.
Điều này trái ngược với ngăn xếp , nơi lưu trữ các kiểu nguyên thủy như int và ký tự, và thường là các biến cục bộ và giá trị trả về của hàm. Đây không phải là rác được thu gom.
Các không gian perm đề cập đến một phần đặc biệt của heap. Xem câu trả lời SO này để được giải thích: Không gian hoán vị là gì?
-XX:MaxPermSize=256m
để đặt kích thước không gian cố định thành 256MB.
Cá nhân tôi sẽ không coi PermGen là một phần đặc biệt của đống.
Tôi thích nghĩ về heap như một vùng bộ nhớ dành riêng để lưu trữ các cá thể đối tượng trong khi PermGen là một vùng dành riêng để lưu trữ các định nghĩa lớp. Do đó, vòng đời của heap được gắn với một ứng dụng trong khi vòng đời của PermGen được gắn với JVM.
Một trong những ví dụ tốt nhất tại sao một ứng dụng và JVM của nó có thể có vòng đời khác nhau là trong một vùng chứa Java EE. Trong máy chủ ứng dụng, các ứng dụng có thể được triển khai và không được triển khai mà không cần khởi động lại máy chủ. Trong quá trình không triển khai (hoặc triển khai lại), thật dễ dàng để giải phóng tất cả các cá thể đối tượng tức là không gian đống, nhưng khá khó để xóa tất cả các lớp được tải bởi ứng dụng này khỏi PermGen vì một số lớp vẫn có thể được tham chiếu bởi JVM.
Một trong những trường hợp như vậy là Trình điều khiển bị rò rỉ . Khi một ứng dụng được triển khai, trình điều khiển JDBC được tải và đăng ký với DriverManager. Khi ứng dụng này không được triển khai, DriverManager vẫn tồn tại và giữ một tham chiếu đến trình điều khiển, trình tải lớp ban đầu của nó và mọi thứ mà trình tải lớp này đã tải. Do đó, một rò rỉ bộ nhớ trong PermGen được tạo ra, nhưng không phải do lỗi quản lý bộ nhớ của ứng dụng.
Đúng là các JVM như JRocket hoàn toàn không có PermGen, mọi thứ đều được lưu trữ trong heap. Chỉ trong bối cảnh như vậy, bạn mới có thể gọi PermGen là một "phần đặc biệt" của đống. Ngay cả khi đó, chúng ta vẫn nên xem PermGen và heap khác nhau vì chúng có mục đích rất khác nhau và chúng có các kiểu rò rỉ bộ nhớ rất khác nhau.
Cập nhật : Trong Oracle's JDK 8, PermGen được thay thế bằng "Metaspace" và bây giờ nó chính thức là một phần của heap. Chúng tôi sẽ không cần phải điều chỉnh PermGen cụ thể nữa.
Bạn KHÔNG thể đặt tên cho bộ nhớ được cấp phát trong heap.
Điều đó có nghĩa là int x
(tên của nó) được cấp phát trong ngăn xếp. Bạn có thể tiếp cận con trỏ theo tên của nó, vì vậy con trỏ nằm trong ngăn xếp. Bạn không thể tiếp cận đối tượng bằng tên của nó, vì nó không có tên. Truy cập vào đối tượng (không tên) phải bằng con trỏ của nó.