PermGen กับ Metaspace ต่างกันอย่างไร?


118

จนกระทั่ง Java 7 มีพื้นที่ในหน่วยความจำ JVM ที่เรียกว่าPermGenซึ่ง JVM ใช้เพื่อเก็บคลาสไว้ ในJava 8มันถูกลบออกไปและแทนที่ด้วยพื้นที่ที่เรียกว่าMetaspace

อะไรคือความแตกต่างที่สำคัญที่สุดระหว่าง PermGen และ Metaspace?

ข้อแตกต่างเดียวที่ฉันรู้คือjava.lang.OutOfMemoryError: PermGen spaceไม่สามารถโยนได้อีกต่อไปและพารามิเตอร์ VM MaxPermSizeจะถูกละเว้น


ผลลัพธ์แรกของ Google: infoq.com/articles/Java-PERMGEN-Removed
the8472

@ the8472 ใช่ แต่ผลลัพธ์นี้ (และอื่น ๆ อีกมากมาย) ของ Google อธิบายเฉพาะกลไกของ Metaspace โดยไม่ได้กล่าวถึงความแตกต่างที่แน่นอนระหว่างสิ่งนี้กับ PermGen
เก้า

คำตอบ:


137

ความแตกต่างหลักจากมุมมองของผู้ใช้ซึ่งฉันคิดว่าคำตอบก่อนหน้านี้ไม่เน้นเพียงพอ - โดยค่าเริ่มต้น Metaspace จะเพิ่มขนาดของมันโดยอัตโนมัติ (ขึ้นอยู่กับสิ่งที่ระบบปฏิบัติการพื้นฐานมีให้) ในขณะที่ PermGen มีขนาดสูงสุดคงที่เสมอ คุณสามารถตั้งค่าสูงสุดคงที่สำหรับ Metaspace ด้วยพารามิเตอร์ JVM แต่คุณไม่สามารถเพิ่ม PermGen อัตโนมัติได้

ในระดับใหญ่มันเป็นเพียงการเปลี่ยนชื่อ ย้อนกลับไปเมื่อมีการเปิดตัว PermGen ไม่มีการโหลด Java EE หรือไดนามิกคลาส (un) ดังนั้นเมื่อโหลดคลาสแล้วจะติดอยู่ในหน่วยความจำจนกว่า JVM จะปิดตัวลงจึงเป็นการสร้างแบบถาวร ปัจจุบันคลาสอาจถูกโหลดและยกเลิกการโหลดในช่วงอายุการใช้งานของ JVM ดังนั้น Metaspace จึงมีความหมายมากขึ้นสำหรับพื้นที่ที่เก็บข้อมูลเมตา

ทั้งของพวกเขามีjava.lang.Classอินสแตนซ์และทั้งสองของพวกเขาทนทุกข์ทรมานจากการรั่วไหลของ ClassLoader ข้อแตกต่างเพียงอย่างเดียวคือด้วยการตั้งค่าเริ่มต้นของ Metaspace จะใช้เวลานานกว่าจนกว่าคุณจะสังเกตเห็นอาการ (เนื่องจากมันเพิ่มขึ้นโดยอัตโนมัติมากที่สุดเท่าที่จะทำได้) กล่าวคือคุณเพียงแค่ผลักปัญหาออกไปโดยไม่ต้องแก้ไข OTOH ฉันคิดว่าผลกระทบของการใช้หน่วยความจำระบบปฏิบัติการจนหมดอาจรุนแรงกว่าการใช้ JVM PermGen จนหมดดังนั้นฉันจึงไม่แน่ใจว่าจะมีการปรับปรุงมากน้อยเพียงใด

ไม่ว่าคุณจะใช้ JVM กับ PermGen หรือ Metaspace ถ้าคุณกำลังทำขนชั้นแบบไดนามิกคุณควรจะใช้มาตรการป้องกันการรั่วไหลของ ClassLoader เช่นโดยการใช้ของฉันห้องสมุด ClassLoader รั่วป้องกัน


17
ทั้ง Permgen หรือ Metaspace ไม่มีอินสแตนซ์ของคลาสคลาส พวกเขาเก็บข้อมูลเมตาเกี่ยวกับคลาสที่โหลดเท่านั้น อินสแตนซ์ของคลาสคลาสจะถูกเก็บไว้ในฮีปปกติเช่นเดียวกับอินสแตนซ์ของคลาสอื่น ๆ
เฉลี่ยโจ

การเปรียบเทียบที่ดี ขอบคุณ
Sandeep

1
อย่างไรก็ตาม OTOH หมายถึง "ในทางกลับกัน"
sofs1

43

ลาก่อน PermGen สวัสดี Metaspace

PermGenถูกลบออกทั้งหมด

การรวบรวมขยะ Metaspace - การรวบรวมขยะของคลาสที่ตายแล้วและตัวโหลดคลาสจะถูกทริกเกอร์เมื่อการใช้งานข้อมูลเมตาของคลาสไปถึงไฟล์MaxMetaspaceSize.

พื้นที่Metadataที่จัดขึ้นจะไม่ต่อเนื่องกันกับJava heapที่ตอนนี้ได้ย้ายหน่วยความจำพื้นเมืองไปยังพื้นที่ที่เรียกว่าmetadataMetaspace

ในคำง่ายๆ ,

เนื่องจากข้อมูลเมตาของคลาสถูกจัดสรรออกจากหน่วยความจำดั้งเดิมพื้นที่ว่างสูงสุดที่พร้อมใช้งานคือหน่วยความจำระบบทั้งหมดที่มีอยู่ ดังนั้นคุณจะไม่พบอีกต่อไปOOM errorsและอาจจะล้นเข้าไปในพื้นที่แลกเปลี่ยน

การลบPermGenไม่ได้หมายความว่าปัญหาการรั่วไหลของตัวโหลดคลาสของคุณจะหมดไป ใช่แล้วคุณยังคงต้องตรวจสอบการบริโภคของคุณและวางแผนตามนั้นเนื่องจากการรั่วไหลจะทำให้หน่วยความจำดั้งเดิมของคุณหมดไป

บทความอื่น ๆ พร้อมการวิเคราะห์: Link1 , Link2และสิ่งนี้


6
แทนที่จะใช้ MaxPermGen คุณมี MaxMetaspaceSize ดังนั้นจึงไม่มีเหตุผลที่จะใช้หน่วยความจำมากขึ้นหรือน้อยลงหรือคุณมีการควบคุมน้อยลง
Peter Lawrey

2
เรากำลังพูดถึงความทรงจำอะไรที่นี่? หน่วยความจำ RAM หรือหน่วยความจำ HDD
Dinesh

1
@Dinesh RAM (หน่วยความจำภายใน)
Aditya Gupta

10

ในระยะสั้น Metaspace ขนาดอัตโนมัติจะเพิ่มขึ้นในหน่วยความจำเนทีฟตามความจำเป็นในการโหลดข้อมูลเมตาของคลาสหากไม่ถูก จำกัด ด้วย -XX:MaxMetaspaceSize

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.