Bộ nhớ java được chia như thế nào?


224

Tôi hiện đang theo dõi một ứng dụng Java với jconsole. Tab bộ nhớ cho phép bạn chọn giữa:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

Sự khác biệt giữa chúng là gì ?


Giả sử rằng bạn đang sử dụng Sun JDK, câu trả lời tốt nhất sẽ được tìm thấy trong tài liệu của họ: Điều chỉnh Bộ sưu tập Rác (JDK 1.5)Câu hỏi thường gặp về Bộ sưu tập Rác (JDK 1.4)
kdgregory

Câu trả lời:


327

Bộ nhớ đống

Bộ nhớ heap là vùng dữ liệu thời gian chạy mà Java VM phân bổ bộ nhớ cho tất cả các thể hiện và mảng của lớp. Heap có thể có kích thước cố định hoặc thay đổi. Trình thu gom rác là một hệ thống quản lý bộ nhớ tự động, phục hồi bộ nhớ heap cho các đối tượng.

  • Eden Space : Nhóm từ đó bộ nhớ ban đầu được phân bổ cho hầu hết các đối tượng.

  • Không gian sống sót : Bể chứa các vật thể sống sót sau bộ sưu tập rác của không gian Eden.

  • Tenured Generation hoặc Old Gen : Bể chứa các vật thể tồn tại một thời gian trong không gian sống sót.

Bộ nhớ không heap

Bộ nhớ không heap bao gồm một vùng phương thức được chia sẻ giữa tất cả các luồng và bộ nhớ cần thiết cho xử lý nội bộ hoặc tối ưu hóa cho máy ảo Java. Nó lưu trữ các cấu trúc trên mỗi lớp như nhóm hằng số thời gian chạy, dữ liệu trường và phương thức và mã cho các phương thức và hàm tạo. Vùng phương thức là một phần logic của heap, nhưng tùy thuộc vào việc triển khai, một máy ảo Java có thể không thu gom hoặc nén nó. Giống như bộ nhớ heap, vùng phương thức có thể có kích thước cố định hoặc thay đổi. Bộ nhớ cho vùng phương thức không cần phải liền kề nhau.

  • Tạo vĩnh viễn : Nhóm chứa tất cả dữ liệu phản chiếu của chính máy ảo, chẳng hạn như các đối tượng lớp và phương thức. Với các máy ảo Java sử dụng chia sẻ dữ liệu lớp, thế hệ này được chia thành các khu vực chỉ đọc và đọc.

  • Bộ đệm mã: Máy ảo Java HotSpot cũng bao gồm bộ đệm mã, chứa bộ nhớ được sử dụng để biên dịch và lưu trữ mã gốc.

Dưới đây là một số tài liệu về cách sử dụng Jconsole .


4
Tôi không chắc chắn @dfa hoàn toàn chính xác vì Thông số kỹ thuật của Máy ảo Java nêu rõ: Vương Mặc dù khu vực phương thức là một phần logic của heap, các triển khai đơn giản có thể chọn không thu gom rác hoặc nén nó. Tuy nhiên, rõ ràng jconsole hiển thị Bộ đệm mã và thế hệ vĩnh viễn là Không phải Heap, điều đó dường như mâu thuẫn với đặc tả. Bất cứ ai có thể cung cấp làm rõ hơn về mâu thuẫn này?
James Bloom

@JamesBloom - Tôi đã tự hỏi tương tự. Mặc dù định nghĩa cơ bản cho biết nhóm bộ nhớ nào thuộc loại nào (heap / non-heap), nhưng nó có thể thay đổi trạng thái rõ ràng không?
Umang Desai

2
tài liệu này được đặt biệt danh từ: docs.intergral.com/pages/viewpage.action?pageId=22478944 Tài liệu chứa một số thông tin tốt khác về JVM, đáng để duyệt
Steve Siebert

1
Mặc dù có rất nhiều sự ủng hộ, nhưng thực sự đó không phải là câu trả lời có ý nghĩa. Ví dụ: "các vật thể sống sót trong bộ sưu tập rác của không gian Eden" nghĩa là gì? Có phải những vật thể này được chuyển đến Không gian sống sót từ Eden sau khi sống sót, hoặc không gian của chúng ở Eden được coi là không gian sống sót? Và những gì về bộ sưu tập rác trong các hồ khác ngoài không gian Eden, nó có xảy ra không? Hoàn toàn không rõ ràng.
Mikhail Batcer 11/03/2016

và đừng quên stack (về phía không heap) :)
Seer Seer

70

Từ khóa mới phân bổ bộ nhớ trên heap Java. Heap là nhóm bộ nhớ chính, có thể truy cập được cho toàn bộ ứng dụng. Nếu không có đủ bộ nhớ để phân bổ cho đối tượng đó, JVM sẽ cố gắng lấy lại một số bộ nhớ từ đống với bộ sưu tập rác. Nếu nó vẫn không thể có đủ bộ nhớ, OutOfMemoryError sẽ bị ném và JVM thoát.

Heap được chia thành nhiều phần khác nhau, được gọi là các thế hệ. Khi các đối tượng tồn tại nhiều bộ sưu tập rác hơn, chúng được phát huy thành các thế hệ khác nhau. Các thế hệ cũ không được thu gom rác thường xuyên. Bởi vì những vật thể này đã được chứng minh là tồn tại lâu hơn, nên chúng ít có khả năng là rác được thu gom.

Khi các vật thể được xây dựng lần đầu tiên, chúng được phân bổ trong Không gian Eden. Nếu chúng sống sót trong một bộ sưu tập rác, chúng được thăng cấp lên Không gian sống sót và nếu chúng sống đủ lâu ở đó, chúng sẽ được phân bổ cho Thế hệ bị chiếm giữ. Thế hệ này là rác được thu thập ít thường xuyên hơn.

Ngoài ra còn có một thế hệ thứ tư, được gọi là Thế hệ vĩnh viễn, hoặc PermGen. Các đối tượng cư trú ở đây không đủ điều kiện để được thu gom rác và thường chứa trạng thái bất biến cần thiết để JVM chạy, chẳng hạn như định nghĩa lớp và nhóm hằng chuỗi. Lưu ý rằng không gian PermGen được lên kế hoạch xóa khỏi Java 8 và sẽ được thay thế bằng một không gian mới gọi là Metaspace, sẽ được giữ trong bộ nhớ riêng. tham khảo ý tưởng http://www.programcalet.com/2013/04/jvm-run-time-data-areas/

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


Sơ đồ có vẻ rất tự giải thích ... Điều này có hợp lệ cho bất kỳ thuật toán GC nào không. G1 có bộ khác nhau.
Venkateswara Rao

@Pythoner Tôi nghĩ rằng cờ có màu tím đậm nên -XX:PermSizevà không phải -XX:MaxPermSizevì nó đã được xác định ở trên.
Anurag


23

Bộ nhớ heap Java là một phần của bộ nhớ được phân bổ cho JVM bởi Hệ điều hành.

Các đối tượng cư trú trong một khu vực được gọi là đống. Heap được tạo khi JVM khởi động và có thể tăng hoặc giảm kích thước trong khi ứng dụng chạy. Khi đống chất đầy, rác được thu gom.

nhập mô tả hình ảnh ở đây

Bạn có thể tìm thêm chi tiết về Eden Space, Survivor Space, Tenured Space và Permanent Generation trong câu hỏi SE bên dưới:

Thế hệ trẻ, Tenured và Perm

PermGen đã được thay thế bằng Metaspace kể từ khi phát hành Java 8.

Về truy vấn của bạn:

  1. Eden Space, Survivor Space, Tenured Space là một phần của bộ nhớ heap
  2. Metaspace và Code Cache là một phần của bộ nhớ không heap.

Codecache: Máy ảo Java (JVM) tạo mã gốc và lưu trữ nó trong một vùng nhớ gọi là codecache. JVM tạo mã gốc vì nhiều lý do, bao gồm cả vòng lặp trình thông dịch được tạo động, sơ khai Giao diện gốc Java (JNI) và cho các phương thức Java được biên dịch thành mã gốc bởi trình biên dịch (JIT) chỉ trong thời gian. JIT cho đến nay là người dùng lớn nhất của codecache.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.