Soft Reference - ใช้สำหรับแคชที่คำนึงถึงหน่วยความจำ
Soft Reference เหมาะสำหรับการสร้างแคชที่สามารถปล่อยหน่วยความจำได้เมื่อ JVM ต้องการพื้นที่
ตัวอย่างโค้ด
import java.lang.ref.SoftReference;
class Demo {
public void displayMsg() {
System.out.println("Hello there");
}
}
public class DemoExample {
public static void main(String[] args) {
Demo myInstance = new Demo();
myInstance.displayMsg();
SoftReference mySoftRef = new SoftReference<>(myInstance);
myInstance = null; // ตัด reference ปกติออก
myInstance = mySoftRef.get(); // ดึงคืนผ่าน soft reference
if (myInstance != null) {
myInstance.displayMsg();
} else {
System.out.println("Object ถูก garbage collect แล้ว");
}
}
}
ผลลัพธ์
Hello there Hello there
คำอธิบาย: สร้างอ็อบเจกต์ Demo เรียกเมธอด แล้วห่อด้วย SoftReference ตั้งค่า reference ต้นฉบับเป็น null แล้วดึงคืนผ่าน get() ถ้ายังไม่ถูก GC จะได้อ็อบเจกต์กลับมา
Phantom Reference - ใช้สำหรับการทำความสะอาดก่อนทำลาย (pre-mortem cleanup)
Phantom Reference ให้ความยืดหยุ่นมากกว่า finalize() สำหรับจัดการทรัพยากรก่อนที่อ็อบเจกต์จะถูกทำลายจริงๆ
ตัวอย่างโค้ด
import java.lang.ref.*;
class Demo {
public void displayMsg() {
System.out.println("Hello there");
}
}
public class DemoExample {
public static void main(String[] args) {
Demo myInstance = new Demo();
myInstance.displayMsg();
ReferenceQueue refQueue = new ReferenceQueue<>();
PhantomReference phantomRef = new PhantomReference<>(myInstance, refQueue);
myInstance = null; // ตัด reference ออก
System.gc(); // ขอให้ GC ทำงาน
// phantomRef.get() จะคืนค่า null เสมอ
Demo retrieved = phantomRef.get();
if (retrieved != null) {
retrieved.displayMsg();
} else {
System.out.println("Phantom reference get() คืนค่า null เสมอ");
}
// รอใน ReferenceQueue เพื่อทำ cleanup
try {
Reference extends Demo> ref = refQueue.remove(1000);
if (ref != null) {
System.out.println("ทำ cleanup actions ที่นี่");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ผลลัพธ์
Hello there Phantom reference get() คืนค่า null เสมอ ทำ cleanup actions ที่นี่
คำอธิบาย: PhantomReference.get() คืนค่า null เสมอ ไม่สามารถดึงอ็อบเจกต์กลับมาได้ ใช้ร่วมกับ ReferenceQueue เพื่อรับทราบเมื่ออ็อบเจกต์จะถูกทำลาย แล้วจึงดำเนินการ cleanup
ความแตกต่างสำคัญ: Soft reference ยังดึงอ็อบเจกต์กลับมาได้ (ถ้ายังไม่ถูก GC) แต่ Phantom reference ดึงไม่ได้ ต้องใช้ queue แจ้งเตือนแทน