2014-11-25 20 views
69

Cho đến khi Java 7 có một vùng trong bộ nhớ JVM được gọi là PermGen, nơi JVM sử dụng để giữ cho các lớp của nó. Trong Java 8 nó đã được gỡ bỏ và thay thế bằng khu vực được gọi là Metaspace.Sự khác nhau giữa PermGen và Metaspace là gì?

Sự khác biệt quan trọng nhất giữa PermGen và Metaspace là gì?

Sự khác biệt duy nhất tôi biết là không thể ném java.lang.OutOfMemoryError: PermGen space và thông số VM MaxPermSize bị bỏ qua.

+0

đầu tiên kết quả google: http://www.infoq.com/articles/Java-PERMGEN-Removed – the8472

+0

@ the8472 Vâng, nhưng điều này (và nhiều người khác) kết quả google mô tả cơ chế Metaspace chỉ, không đề cập đến bất cứ điều gì về sự khác biệt chính xác giữa điều này và PermGen. – Kao

Trả lời

77

Sự khác biệt chính từ góc độ người dùng - mà tôi nghĩ câu trả lời trước đó không nhấn mạnh đủ - là Metaspace bằng tự động mặc định tăng của nó kích thước (tối đa những gì mà hệ điều hành bên dưới cung cấp), trong khi PermGen luôn có kích thước tối đa cố định. Bạn có thể đặt tối đa cố định cho Metaspace với các tham số JVM, nhưng bạn không thể làm cho PermGen tự động tăng lên.

Ở mức độ lớn, đó chỉ là thay đổi tên. Quay lại khi PermGen được giới thiệu, không có Java EE hoặc lớp động (un) tải, vì vậy khi một lớp đã được tải nó đã bị kẹt trong bộ nhớ cho đến khi JVM tắt - do đó, Vĩnh viễn Thế hệ. Ngày nay các lớp có thể được nạp và tải trong suốt thời gian tồn tại của JVM, vì vậy Metaspace có ý nghĩa hơn đối với khu vực nơi siêu dữ liệu được lưu giữ.

Cả hai trường hợp đều chứa java.lang.Class trường hợp và cả hai trường hợp đều bị ClassLoader leaks. Chỉ có sự khác biệt là với cài đặt mặc định Metaspace, phải mất nhiều thời gian hơn cho đến khi bạn nhận thấy các triệu chứng (vì nó tự động tăng nhiều nhất có thể), tức là bạn chỉ cần đẩy vấn đề ra xa hơn mà không cần giải quyết. OTOH Tôi tưởng tượng hiệu quả của việc chạy bộ nhớ hệ điều hành có thể nghiêm trọng hơn là chỉ cần chạy ra khỏi JVM PermGen, vì vậy tôi không chắc nó có nhiều cải thiện hay không.

Cho dù bạn đang sử dụng JVM với PermGen hoặc với Metaspace, nếu bạn đang thực hiện xếp lớp động, bạn nên thực hiện các biện pháp chống rò rỉ bộ nạp lớp, ví dụ bằng cách sử dụng ClassLoader Leak Prevention library.

+3

Cả Permgen lẫn Metaspace đều không chứa các cá thể của lớp Class. Họ chỉ giữ thông tin meta về các lớp đã tải. Các cá thể của lớp Class được giữ trong vùng heap thông thường, giống như các cá thể của các lớp khác. –

+0

So sánh tốt đẹp. Cảm ơn – Sandeep

23

Bye, Bye PermGen, Hello Metaspace

PermGen đã được loại bỏ hoàn toàn.

Thu gom rác Metaspace - Thu gom rác của các lớp đã chết và trình nạp lớp được kích hoạt khi sử dụng siêu dữ liệu lớp đạt đến MaxMetaspaceSize.

Không gian Metadata đã được giữ không còn tiếp giáp với Java heap, metadata hiện đã được chuyển sang bộ nhớ riêng sang một khu vực được gọi là Metaspace.

Nói cách đơn giản,

Kể từ khi siêu dữ liệu lớp được phân bổ ra khỏi bộ nhớ quê hương, không gian có sẵn max là tổng bộ nhớ hệ thống có sẵn. Do đó, bạn sẽ không còn gặp phải OOM errors và có thể sẽ tràn vào không gian hoán đổi.

Việc xóa PermGen không có nghĩa là các sự cố rò rỉ trình tải lớp của bạn đã biến mất. Vì vậy, có, bạn vẫn sẽ phải theo dõi mức tiêu thụ của bạn và lập kế hoạch cho phù hợp, vì rò rỉ sẽ kết thúc tiêu thụ toàn bộ bộ nhớ riêng của bạn.

Một số bài báo khác, với phân tích: Link1, Link2, và this

+6

Thay vì MaxPermGen bạn có MaxMetaspaceSize, vì vậy không có lý do gì nó sẽ sử dụng nhiều hơn, hoặc ít bộ nhớ hơn hoặc bạn có ít quyền kiểm soát hơn. –

5

Nói tóm lại, Metaspace kích thước tự động tăng trong bộ nhớ mẹ đẻ theo yêu cầu để tải lớp siêu dữ liệu nếu không bị hạn chế với -XX:MaxMetaspaceSize

Các vấn đề liên quan