การทำงานกับการสร้างวัตถุ

ตัวรวบรวมขยะ Java ใช้กลยุทธ์การรวบรวมขยะรุ่นที่สามารถจำแนกวัตถุตามอายุ

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

พื้นที่หน่วยความจำฮีปใน JVM แบ่งออกเป็นสามส่วน:

การทำงานกับการสร้างวัตถุ

รุ่นน้อง

วัตถุที่สร้างขึ้นใหม่เริ่มขึ้นในคนรุ่นใหม่ คนรุ่นใหม่แบ่งออกเป็นสองประเภทเพิ่มเติม

  • Eden Space - วัตถุใหม่ทั้งหมดเริ่มต้นที่นี่ พวกมันได้รับการจัดสรรหน่วยความจำเริ่มต้น
  • Survivor Spaces (FromSpace และ ToSpace) - วัตถุจะถูกย้ายจาก Eden มาที่นี่หลังจากรอดชีวิตจากรอบการเก็บขยะหนึ่งรอบ

กระบวนการเมื่อวัตถุเป็นขยะที่รวบรวมจากรุ่นน้องเรียกว่าเหตุการณ์การรวบรวมขยะเล็กน้อย

เมื่อพื้นที่ของ Eden เต็มไปด้วยวัตถุ จะมีการเก็บรวบรวมขยะขนาดเล็ก วัตถุที่ตายแล้วทั้งหมดจะถูกลบออก และสิ่งมีชีวิตทั้งหมดจะถูกย้ายไปยังหนึ่งในสองช่องว่างที่เหลือ GC ขนาดเล็กยังตรวจสอบวัตถุในพื้นที่ของผู้รอดชีวิตและย้ายไปยังพื้นที่อื่น (ถัดไป) ผู้รอดชีวิต

ลองใช้ลำดับต่อไปนี้เป็นตัวอย่าง

  1. มีวัตถุทั้งสองประเภท (มีชีวิตและตายแล้ว) ในสวนอีเดน
  2. GC ขนาดเล็กเกิดขึ้น - วัตถุที่ตายแล้วทั้งหมดจะถูกลบออกจาก Eden วัตถุที่มีชีวิตทั้งหมดจะถูกย้ายไปที่ space-1 (FromSpace) Eden และ space-2 ว่างเปล่าแล้ว
  3. วัตถุใหม่ถูกสร้างขึ้นและเพิ่มเข้าไปในสวนอีเดน วัตถุบางอย่างใน Eden และ space-1 นั้นตายแล้ว
  4. GC ขนาดเล็กเกิดขึ้น - วัตถุที่ตายแล้วทั้งหมดจะถูกลบออกจาก Eden และ space-1 วัตถุที่มีชีวิตทั้งหมดจะถูกย้ายไปยัง space-2 (ToSpace) Eden และ space-1 ว่างเปล่า

ดังนั้น ไม่ว่าเวลาใด พื้นที่หนึ่งของผู้รอดชีวิตจะว่างเปล่าเสมอ เมื่อผู้รอดชีวิตถึงเกณฑ์ที่กำหนดในการเคลื่อนที่ผ่านช่องว่างของผู้รอดชีวิต พวกเขาก็จะก้าวไปสู่คนรุ่นเก่า

คุณสามารถใช้แฟ ล็ ก -Xmnเพื่อตั้งค่าขนาดคนรุ่นใหม่

คนรุ่นเก่า

ออบเจกต์ที่มีอายุมาก (เช่น ตลอดอายุการใช้งานของโปรแกรม) จะกลายเป็นอ็อบเจกต์ที่มีอายุมากกว่า - อายุร้อยปี มันถูกเรียกว่ารุ่นปกติและมีวัตถุที่ถูกทิ้งไว้ใน Survivor Spaces มาเป็นเวลานาน

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

คุณสามารถใช้ แฟล็ ก-Xmsและ-Xmx เพื่อตั้งค่าขนาดหน่วยความจำฮีปเริ่มต้นและสูงสุด

เนื่องจาก Java ใช้การรวบรวมขยะในรุ่น ยิ่งมีการรวบรวมขยะมากเท่าไหร่ประสบการณ์ของอ็อบเจ็กต์ก็จะยิ่งเคลื่อนไปบนฮีปมากขึ้นเท่านั้น เขาเริ่มต้นในรุ่นเยาว์และในที่สุดก็จบลงในรุ่นปกติหากมีอายุยืนยาวพอ

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

เมื่อวัตถุถูกสร้างขึ้น สิ่งนั้นจะถูกวางไว้ในพื้นที่ Eden ของคนรุ่นใหม่

ทันทีที่มีการรวบรวมขยะขนาดเล็ก วัตถุที่มีชีวิตจาก Eden จะถูกย้ายไปยัง FromSpace เมื่อการรวบรวมขยะย่อยครั้งต่อไปเกิดขึ้น วัตถุที่มีชีวิตจากทั้ง Eden และอวกาศจะถูกย้ายไปยัง ToSpace

วัฏจักรนี้ดำเนินต่อไปตามจำนวนครั้งที่กำหนด หากวัตถุยังคง "ให้บริการ" หลังจากจุดนี้ รอบการรวบรวมขยะถัดไปจะย้ายไปยังพื้นที่รุ่นเก่า

การสร้างถาวรและ metaspace

ข้อมูลเมตาเช่นคลาสและเมธอดจะถูกเก็บไว้ในรุ่นถาวร JVM เติมที่รันไทม์ตามคลาสที่ใช้โดยแอปพลิเคชัน คลาสที่ไม่ใช้แล้วสามารถเปลี่ยนจากการสร้างถาวรเป็นขยะ

คุณสามารถใช้แฟล็ก -XX:PermGenและ-XX:MaxPermGenเพื่อตั้งค่าเริ่มต้นและขนาดสูงสุดของการสร้างถาวร

พื้นที่เมตา

ตั้งแต่ Java 8 พื้นที่ PermGen ถูกแทนที่ด้วยพื้นที่หน่วยความจำ MetaSpace การใช้งานแตกต่างจาก PermGen - พื้นที่ฮีปนี้เปลี่ยนไปโดยอัตโนมัติ

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