8.1 การอ้างอิงที่อ่อนแอใน Java

มีการอ้างอิงหลายประเภทใน Java

มีStrongReferenceซึ่งเป็นลิงก์ทั่วไปที่เราสร้างขึ้นทุกวัน

Object object = new Object();//created an object
object = null;//can now be garbage collected

และมีลิงก์ประเภท "พิเศษ" สามประเภท ได้แก่ SoftReference, WeakReference, PhantomReference ในความเป็นจริง มีเพียงความแตกต่างเพียงอย่างเดียวระหว่างลิงก์ทุกประเภท นั่นคือพฤติกรรมของ GC กับอ็อบเจ็กต์ที่พวกเขาอ้างถึง เราจะพูดถึงรายละเอียดเฉพาะของลิงก์แต่ละประเภทในภายหลัง แต่สำหรับตอนนี้ ความรู้ต่อไปนี้ก็เพียงพอแล้ว:

  • SoftReferenceคือการอ้างอิงแบบซอฟต์ หาก GC เห็นว่าอ็อบเจ็กต์สามารถเข้าถึงได้ผ่านห่วงโซ่ของการอ้างอิงแบบซอฟต์เท่านั้น ก็จะลบออกจากหน่วยความจำ อาจจะ.
  • WeakReference - การอ้างอิงที่อ่อนแอ หาก GC เห็นว่าวัตถุนั้นสามารถเข้าถึงได้ผ่านห่วงโซ่ของการอ้างอิงที่อ่อนแอเท่านั้น ก็จะลบสิ่งนั้นออกจากหน่วยความจำ
  • PhantomReferenceเป็นการอ้างอิงแบบหลอน ถ้า GC เห็นว่าออบเจกต์นั้นมีอยู่ผ่านเชนของการอ้างอิงแบบหลอนเท่านั้น ก็จะลบสิ่งนั้นออกจากหน่วยความจำ หลังจากรัน GC มาหลายรอบ

คุณสามารถพูดได้ว่าประเภทลิงก์มีความนุ่มนวลในระดับหนึ่ง:

  • ฮาร์ดลิงก์ปกติคือตัวแปรของประเภทการอ้างอิง ไม่ถูกเก็บกวาดโดยคนเก็บขยะก่อนที่จะใช้งานไม่ได้
  • ซอฟต์รีเพอเรอร์ อ็อบเจกต์จะไม่ทำให้หน่วยความจำทั้งหมดถูกใช้งาน - รับประกันว่าจะถูกลบก่อนที่จะเกิด OutOfMemoryError อาจเร็วกว่านั้นขึ้นอยู่กับการใช้งานของตัวรวบรวมขยะ
  • การอ้างอิงที่อ่อนแอ อ่อนกว่า. ไม่ป้องกันออบเจกต์จากการกำจัด ตัวรวบรวมขยะละเว้นการอ้างอิงดังกล่าว
  • PhantomReference . ใช้สำหรับการประมวลผล "ตาย" ของวัตถุ: วัตถุจะพร้อมใช้งานหลังจากการสรุปผลจนกว่าจะมีการรวบรวมขยะ

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

8.2 WeakReference และ SoftReference ใน Java

ก่อนอื่น มาดูความแตกต่างระหว่างWeakReferenceและSoftReferenceใน Java

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

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

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

ตัวอย่าง WeakReference ใน Java:

// some object
Student student = new Student();

// weak reference to it
WeakReference weakStudent = new WeakReference(student);

// now the Student object can be garbage collected
student = null;

ตัวอย่าง SoftReference ใน Java:

// some object
Student student = new Student();

// weak reference to it
SoftReference softStudent = new SoftReference(student)

// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory
student = null;

8.3 PhantomReference ใน Java

อินสแตนซ์ PhantomReference สร้างขึ้นในลักษณะเดียวกับในตัวอย่าง WeakReference และ SoftReference แต่ไม่ค่อยได้ใช้

PhantomReference สามารถรวบรวมขยะได้หากวัตถุไม่มีการอ้างอิงที่แข็งแกร่ง (แข็งแกร่ง) อ่อนแอ (WeakReference) หรืออ่อนนุ่ม (SoftReference)

คุณสามารถสร้าง Phantom Reference object ได้ดังนี้:

PhantomReference myObjectRef = new PhantomReference(MyObject);

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

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

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

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

undefined
3
Опрос
Working with memory in Java,  18 уровень,  7 лекция
недоступен
Working with memory in Java
Working with memory in Java