เรียกคืนการรวบรวมขยะใน Java

การรวบรวมขยะคือกระบวนการเรียกคืนหน่วยความจำรันไทม์แบบเต็มโดยการทำลายวัตถุที่ไม่ได้ใช้

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

หลังจากถึงจุดหนึ่ง หน่วยความจำไม่เพียงพอที่จะสร้างวัตถุใหม่อีกต่อไป และโปรแกรมจะหยุดทำงานอย่างผิดปกติเนื่องจากOutOfMemoryError

การรวบรวมขยะใน Java เป็นกระบวนการที่โปรแกรม Java จัดการหน่วยความจำโดยอัตโนมัติ โปรแกรม Java ถูกคอมไพล์เป็น bytecode ที่ทำงานบน Java Virtual Machine (JVM)

เมื่อโปรแกรม Java ทำงานบน JVM อ็อบเจ็กต์จะถูกสร้างขึ้นบนฮีป ซึ่งเป็นส่วนของหน่วยความจำที่จัดสรรให้

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

  • สด - วัตถุเหล่านี้ถูกใช้ มันถูกอ้างอิงจากที่อื่น
  • ตาย - วัตถุเหล่านี้ไม่ได้ใช้ที่อื่นไม่มีการอ้างอิงถึงพวกเขา

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

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

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

ความสามารถในการเข้าถึงวัตถุ

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

ความสามารถในการเข้าถึงวัตถุ

คนเก็บขยะทำงานโดยใช้แนวคิดของ GC Roots ( รากของการเก็บขยะ ) เพื่อแยกความแตกต่างระหว่างวัตถุที่มีชีวิตและวัตถุที่ตายแล้ว มีวัตถุมีชีวิต 100% และมีลิงก์ที่ทำให้วัตถุอื่นเคลื่อนไหวเป็นต้น

ตัวอย่างของรากดังกล่าว:

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

ขั้นตอนการรวบรวมขยะใน Java

การดำเนินการรวบรวมขยะมาตรฐานมีสามขั้นตอน

1. ทำเครื่องหมายวัตถุเป็นสด

ณ จุดนี้ ตัวรวบรวมขยะ (GC) จะต้องระบุวัตถุที่มีชีวิตทั้งหมดในหน่วยความจำโดยการสำรวจกราฟวัตถุ

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

2. ทำความสะอาดวัตถุที่ตายแล้ว

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

3. การจัดเรียงวัตถุที่เหลืออยู่ในหน่วยความจำอย่างกะทัดรัด

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

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

กระบวนการบีบอัดช่วยให้จัดสรรหน่วยความจำตามลำดับสำหรับวัตถุใหม่ได้ง่ายขึ้น