JavaRush /จาวาบล็อก /Random-TH /ความแตกต่างระหว่างการอ้างอิงแบบ Weak, Soft, Phantom และ R...
theGrass
ระดับ
Саратов

ความแตกต่างระหว่างการอ้างอิงแบบ Weak, Soft, Phantom และ Regular ใน Java

เผยแพร่ในกลุ่ม
การอ้างอิงแบบ "อ่อนแอ" และการอ้างอิงแบบ "อ่อน" (WeakReference, SoftReference) ได้ถูกเพิ่มลงในJava API เมื่อนานมาแล้ว แต่ไม่ใช่ว่าโปรแกรมเมอร์ทุกคนจะคุ้นเคยกับสิ่งเหล่านี้ สิ่งนี้บ่งบอกถึงช่องว่างในการทำความเข้าใจว่าจะใช้สิ่งเหล่านี้ที่ไหนและอย่างไร คลาสอ้างอิงมีความสำคัญอย่างยิ่งในบริบท ของการ รวบรวมขยะ ดังที่เราทุกคนรู้ ตัวรวบรวมขยะเองก็จะปล่อยหน่วยความจำที่วัตถุครอบครองให้ว่าง แต่ไม่ใช่ว่าโปรแกรมเมอร์ทุกคนจะรู้ว่ามันตัดสินใจเพิ่มหน่วยความจำโดยขึ้นอยู่กับประเภทของการอ้างอิงที่มีให้กับวัตถุนั้น ความแตกต่างระหว่างลิงก์อ่อน, ซอฟต์, phantom และลิงก์ปกติใน Java - 1ข้อแตกต่างที่สำคัญระหว่างSoftReferenceและWeakReferenceคือวิธีที่ตัวรวบรวมจะทำงานร่วมกับพวกมัน มันสามารถลบอ็อบเจ็กต์ได้ตลอดเวลาหากลิงก์ที่อ่อนแอเท่านั้นที่ชี้ไป ในทางกลับกัน อ็อบเจ็กต์ที่มีซอฟต์ลิงก์จะถูกรวบรวมเมื่อJVMต้องการหน่วยความจำจริงๆ เท่านั้น เนื่องจากคุณสมบัติของคลาสอ้างอิงเหล่านี้ แต่ละคลาสจึงมีการใช้งานของตัวเอง SoftReferenceสามารถใช้ในการปรับใช้แคช และเมื่อJVMต้องการหน่วยความจำ มันจะว่างโดยการลบอ็อบเจ็กต์ดังกล่าว และWeakReferencesเหมาะอย่างยิ่งสำหรับการจัดเก็บข้อมูลเมตา เช่น การจัดเก็บลิงก์ไปยัง ClassLoader หากไม่มีคลาสที่จะโหลด ก็ไม่มีประโยชน์ที่จะจัดเก็บข้อมูลอ้างอิงถึงClassLoaderการอ้างอิงที่อ่อนแอจะทำให้ ClassLoader พร้อมสำหรับการลบออกทันทีที่เรากำหนดมัน แทนที่จะเป็นการอ้างอิงที่รัดกุม ในบทความนี้ เราจะดูความแตกต่างระหว่างประเภทลิงก์ รวมถึงการ อ้างอิงแบบ Strongและการอ้างอิงแบบ Phantom

WeakReference กับ SoftReference ใน Java

สำหรับผู้ที่ไม่ทราบมีลิงค์อยู่ 4 ประเภท:
  1. การอ้างอิงที่แข็งแกร่ง
  2. การอ้างอิงที่อ่อนแอ
  3. การอ้างอิงที่นุ่มนวล
  4. การอ้างอิงผี
Strong Link นั้นง่ายที่สุด เนื่องจากเราใช้มันในการเขียนโปรแกรมทุกวัน เช่น ในโค้ดอย่างString s = “abc”ตัวแปรsคือ Strong Link วัตถุใดๆ ที่มีการอ้างอิงที่ชัดเจนจะถูกห้ามไม่ให้ผู้รวบรวมขยะลบออก แน่นอนว่าสิ่งเหล่านี้เป็นอ็อบเจ็กต์ที่ โปรแกรม Javaต้องการ การอ้างอิงที่อ่อนแอจะแสดงโดย คลาส java.lang.ref.WeakReferenceคุณสามารถกำหนดการอ้างอิงที่อ่อนแอได้ดังนี้:
Counter counter = new Counter(); // strong reference
WeakReference weakCounter = new WeakReference(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection
ตอนนี้ เมื่อคุณตั้งค่าตัวนับการอ้างอิงที่รัดกุมเป็น null (ตัวนับ = null) อ็อบเจ็กต์ที่สร้างขึ้นในบรรทัดแรกจะพร้อมใช้งานสำหรับการรวบรวมการรวบรวมขยะ เนื่องจากไม่มีการอ้างอิงที่รัดกุมอีกต่อไป การอ้างอิงอ่อนแอCounter ที่สร้างโดย Weak ไม่สามารถป้องกันตัวรวบรวมจากการลบอ็อบเจ็กต์ตัวนับ ในทางกลับกัน หากเป็นการอ้างอิงแบบ Soft ออบเจ็กต์ Counter จะไม่ถูกลบจนกว่าJVMจะมีความต้องการหน่วยความจำสูงเป็นพิเศษ การอ้างอิง แบบซอฟต์ในJavaแสดงโดย คลาส java.lang.ref.SoftReference ตัวอย่างการสร้าง SoftReference ในJava
Counter prime = new Counter();  // prime holds a strong reference
SoftReference soft = new SoftReference(prime) ; //soft reference variable has SoftReference to Counter Object
prime = null;  // now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory
หลังจากล้างการอ้างอิงที่รัดกุม (ในบรรทัดที่ 3) แล้ว การอ้างอิงแบบอ่อนเพียง 1 รายการจะยังคงอยู่ที่วัตถุตัวนับ ซึ่งจะไม่สามารถป้องกันตัวรวบรวมขยะจากการลบวัตถุนี้ แต่ต่างจากการอ้างอิงที่อ่อนแอตรงที่จะสามารถเลื่อนออกไปได้ กระบวนการนี้จนเกิดการขาดแคลนหน่วยความจำอย่างเฉียบพลัน เมื่อพิจารณาถึงความแตกต่างระหว่างซอฟต์ลิงก์และลิงก์ที่ไม่รัดกุม ลิงก์แรกเหมาะสำหรับแคชมากกว่า และลิงก์อ่อนสำหรับข้อมูลเมตา ตัวอย่างที่ดีคือคลาส WeakHashMap ซึ่งเป็นคลาสสืบทอดของอินเทอร์เฟซ Map เช่น คลาส HashMapหรือTreeMapแต่มีคุณลักษณะที่โดดเด่นอย่างหนึ่ง WeakHashMapล้อมคีย์ว่าเป็นการอ้างอิงที่ไม่รัดกุม ซึ่งหมายความว่าทันทีที่ไม่มีการอ้างอิงที่รัดกุมไปยังออบเจ็กต์ การอ้างอิงที่ไม่รัดกุมซึ่งอยู่ภายในWeakHashMapจะไม่ช่วยคุณจากตัวรวบรวมขยะ ลิงก์ Phantom เป็นลิงก์ประเภทที่สามที่มีอยู่ในแพ็คเกจ java.lang.ref การอ้างอิง Phantom จะแสดงโดย คลาส java.lang.ref.PhantomReference อ็อบเจ็กต์ที่ชี้ไปโดยลิงก์ Phantom เท่านั้นสามารถลบโดยตัวรวบรวมได้ตลอดเวลา ลิงค์ Phantomถูกสร้างขึ้นในลักษณะเดียวกับลิงค์อ่อนหรือซอฟต์ลิงค์
DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong reference
PhantomReference phantom = new PhantomReference(digit); // phantom reference
digit = null;
เมื่อคุณล้างการอ้างอิงที่รัดกุมไปยังวัตถุ DigitalCounter แล้ว ตัวรวบรวมขยะจะลบออกเมื่อใดก็ได้ เนื่องจากขณะนี้มีเพียงการอ้างอิง phantom เท่านั้นที่ชี้ไปที่วัตถุนั้น นอกจากคลาส WeakReference, SoftReference, PhantomReference, WeakHashMap แล้ว การทราบเกี่ยวกับ คลาส ReferenceQueue ยังมีประโยชน์อีก ด้วย คุณสามารถใช้คลาสนี้เมื่อสร้างวัตถุ WeakReference, SoftReference หรือ PhantomReference:
ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
DigitalCounter digit = new DigitalCounter();
PhantomReference phantom = new PhantomReference(digit, refQueue);
การอ้างอิงวัตถุจะถูกเพิ่มในReferenceQueueและคุณสามารถตรวจสอบสถานะของการอ้างอิงได้โดยการสำรวจ ReferenceQueue วงจรชีวิตของ Object แสดงให้เห็นอย่างดีในแผนภาพนี้ นั่นความแตกต่างระหว่างการอ้างอิงแบบอ่อนแอ, ซอฟต์, phantom และแบบปกติใน Java - 2คือความแตกต่างทั้งหมดระหว่างการอ้างอิงแบบอ่อนแอและแบบซอฟต์ในJava เรายังได้ทำความคุ้นเคยกับลิงค์ Phantom, คลาสWeakHashMapและReferenceQueue การใช้การอ้างอิงอย่างเหมาะสมจะช่วยในการรวบรวมขยะ และจะส่งผลให้การจัดการหน่วยความจำใน Java มีความยืดหยุ่นมาก ขึ้น บทความต้นฉบับ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION