Java: ความแตกต่างระหว่างการอ้างอิง strong / soft / weak / phantom


179

ฉันได้อ่านบทความนี้เกี่ยวกับหัวข้อ แต่ฉันไม่เข้าใจจริงๆ โปรดให้คำแนะนำพร้อมตัวอย่างเมื่ออธิบายแนวคิด



4
ฉันได้อ่านเอกสารนั้นแล้วมันไม่ได้ช่วยให้ฉันจินตนาการถึงความแตกต่างอะไร (อาจเป็นเพราะเป็นเอกสารที่อ่านยาก)

14
หากคุณอ่านบทความนั้นและยังไม่เข้าใจคุณมีคำถามเฉพาะเกี่ยวกับบทความนี้หรือไม่ เป็นการยากที่จะตอบสนองต่อ "โปรดอธิบายให้ฉันฟังหน่อย" "นี่คือความหมาย" "ฉันไม่เข้าใจ" โดยไม่เจาะจงว่าคุณไม่ได้รับส่วนใด
yshavit


@LouisWasserman ลิงค์ด้านบนไม่สามารถใช้งานได้อีกต่อไป
Mehraj Malik

คำตอบ:


142

Java ให้ทั้งสองประเภทที่แตกต่างกัน / ชั้นเรียนของวัตถุอ้างอิง : แข็งแกร่งและอ่อนแอ วัตถุอ้างอิงที่อ่อนแอสามารถแบ่งออกเป็นอ่อนและphantomเพิ่มเติม

  • แข็งแรง
  • อ่อนแอ
    • อ่อนนุ่ม
    • ผี

ไปกันทีละจุด

วัตถุอ้างอิงที่แข็งแกร่ง

StringBuilder builder = new StringBuilder();

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

วัตถุอ้างอิงที่อ่อนแอ

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

Weak Reference Object ไม่ใช่ประเภท / คลาสเริ่มต้นของ Reference Object และควรใช้พวกมันควรถูกระบุอย่างชัดเจนเช่นในตัวอย่างด้านบน การอ้างอิงชนิดนี้ทำให้ออบเจ็กต์การอ้างอิงมีสิทธิ์ได้รับ GC นั่นคือในกรณีที่การอ้างอิงเพียงอย่างเดียวที่สามารถเข้าถึงได้สำหรับStringBuilderวัตถุในหน่วยความจำคือจริงๆแล้วการอ้างอิงที่อ่อนแอจากนั้น GC อนุญาตให้ขยะเก็บรวบรวมStringBuilderวัตถุ เมื่อวัตถุในหน่วยความจำสามารถเข้าถึงได้โดย Weak Reference Objects วัตถุนั้นจะมีสิทธิ์โดยอัตโนมัติสำหรับ GC

ระดับความอ่อนแอ

สองระดับที่แตกต่างกันของความอ่อนแอสามารถเกณฑ์: นุ่มและผี

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

ในทางตรงกันข้ามPhantom Reference Object มีประโยชน์เฉพาะที่จะรู้ว่าเมื่อวัตถุถูกลบออกจากหน่วยความจำอย่างมีประสิทธิภาพ: โดยปกติแล้วพวกเขาจะใช้เพื่อแก้ไขพฤติกรรมแปลกประหลาดสุดท้าย () การฟื้นฟู / การฟื้นคืนชีพเนื่องจากพวกเขาไม่ได้คืนวัตถุเอง ช่วยในการติดตามสถานะหน่วยความจำเท่านั้น

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


76

ข้อมูลอ้างอิงที่อ่อนแอ:

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

อ้างอิงอ่อน:

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

การอ้างอิงผี:

การอ้างอิงแฝงค่อนข้างแตกต่างจาก SoftReference หรือ WeakReference การยึดเกาะกับวัตถุนั้นผอมบางจนคุณไม่สามารถเรียกคืนวัตถุได้ - เมธอด get () จะคืนค่าว่างเสมอ การใช้งานสำหรับการอ้างอิงเท่านั้นคือการติดตามว่าเมื่อใดที่ได้รับการจัดคิวเข้าสู่ ReferenceQueue ณ จุดนั้นคุณจะรู้ว่าวัตถุที่มันชี้ไปนั้นตายไปแล้ว

ข้อความนี้ถูกดึงมาจาก: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references


1
แม้ว่าทุกอย่างในคำตอบนี้จะถูกต้อง แต่ก็ดูเหมือนว่าฉันอาจมีข้อผิดพลาดในเว็บเพจที่เชื่อมโยง Javadoc สำหรับแพคเกจ java.lang.refและว่าสำหรับ PhantomReference ชี้ให้เห็นว่าวัตถุที่ไม่ได้เก็บขยะจนกระทั่งหลังจากที่มันไม่ได้ "ผีเข้าถึงได้" หมายความว่า (เหมือน SoftReference บริการ) PhantomReference จะต้อง dequeued ก่อนวัตถุที่มันหมายถึงสามารถ เป็นขยะที่เก็บรวบรวม ... และการถูกจัดคิวไม่ได้บ่งชี้ว่าหน่วยความจำที่เกี่ยวข้องนั้นได้รับการปลดปล่อย
Theodore Murdock

2
สำหรับบันทึกฉันจะค่อนข้างอยู่ในโลกที่โพสต์บล็อกนั้นถูกต้อง
Theodore Murdock

1
@TheodoreMurdock javadoc นั้นถูกต้อง การอ้างอิงแฝงไม่ได้ขัดขวางการรวบรวมขยะเลย เมื่อวัตถุถูกจัดคิวแล้วจะไม่สามารถบันทึกได้แม้กระทั่งโดยเครื่องมือตัดขั้นสุดท้ายเนื่องจาก Finalizers ได้ทำงานแล้ว มันตายแล้ว แต่ยังไม่หายไป
Leliel

@Leliel จริงอ้างอิงผีไม่ในความเป็นจริงเป็นอุปสรรคต่อการเก็บขยะหลังจากที่มีการจัดคิว ... ฉันรู้ว่าเมื่อเร็ว ๆ นี้เมื่อมีข้อผิดพลาดที่เกิดจากหัวข้อการทำความสะอาดเพื่อออกจากต้น การมีอยู่ของการอ้างอิงแบบแฝงนั้นเพียงพอที่จะตรวจสอบให้แน่ใจว่าทุกวัตถุที่อ้างอิงแบบ phantom ถูกเก็บไว้ในกองการถ่ายโอนข้อมูลของฉันไม่พร้อมใช้งานสำหรับคอลเลกชัน ... หากคุณล้มเหลวในการประมวลผลคิวหรือล้มเหลว และอย่าล้างข้อมูล () การอ้างอิงแฝง) จากนั้นหน่วยความจำของคุณจะรั่วไหลรวมทั้งการอ้างอิงผีและวัตถุที่อ้างอิง
Theodore Murdock

25

ความแตกต่างระหว่างที่เรียบง่ายSoftReferenceและWeakReferenceให้บริการโดยนักพัฒนาซอฟต์แวร์ Android

ความแตกต่างระหว่าง a SoftReferenceและ a WeakReferenceคือเวลาที่การตัดสินใจทำเพื่อให้ชัดเจนและจัดทำเอกสารอ้างอิง:

  • SoftReferenceควรล้างและ enqueued เป็นปลายที่เป็นไปได้นั่นคือในกรณีที่ VM อยู่ในอันตรายจากการทำงานออกจากหน่วยความจำ

  • WeakReferenceอาจจะล้างและ enqueued เร็วที่สุดเท่าที่เป็นที่รู้จักกันอย่างอ่อนอ้างอิง


16

คำศัพท์สามคำที่คุณใช้มักเกี่ยวข้องกับการมีสิทธิ์ของวัตถุในการรวบรวมขยะ

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

Soft Reference :: มันมากหรือน้อยเหมือนการอ้างอิงที่อ่อนแอ แต่คุณสามารถพูดได้ว่ามันเก็บวัตถุได้มากขึ้นกว่าการอ้างอิงที่อ่อนแอจากการรวบรวมขยะ

หากนักสะสมขยะรวบรวมการอ้างอิงที่อ่อนแอในวงจรชีวิตแรกมันจะรวบรวมการอ้างอิงที่อ่อนนุ่มในรอบถัดไปของการรวบรวมขยะ

การอ้างอิงที่แข็งแกร่ง :: ตรงข้ามกับการอ้างอิงสองประเภทข้างต้น พวกเขาชอบเก็บขยะน้อยกว่า (ส่วนใหญ่ไม่เคยถูกรวบรวม)

คุณสามารถดูลิงค์ต่อไปนี้สำหรับข้อมูลเพิ่มเติม:

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html


3
ฉันคิดว่านี่เป็นสิ่งผิด - "ถ้านักสะสมขยะรวบรวมการอ้างอิงที่อ่อนแอในวงจรชีวิตแรกมันจะรวบรวมการอ้างอิงที่อ่อนนุ่มในรอบถัดไปของการรวบรวมขยะ" ไม่จำเป็นต้องเป็นอย่างนั้นคุณจะมั่นใจได้อย่างไรว่าพวกเขาจะเกิดขึ้นในการทำงานต่อเนื่องของ GC? GC สามารถอนุญาตให้ออบเจ็กต์อ้างอิงนุ่ม ๆ อยู่ได้แม้ในการวิ่งครั้งที่ 2 และครั้งที่ 3 ด้วย ไม่มีเอกสารประกอบหากมีโปรดระบุลิงค์ที่ระบุ
Saurabh Patil

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

@SaurabhPatil - พลาดความคิดเห็นของคุณ นี่คือคำตอบ 1. "เขาถามชัดเจนเกี่ยวกับความแตกต่างและความไม่เหมือนกัน" - อ้างถึงคำอธิบายของคำถาม (ไม่ใช่ "เพียง" ชื่อเรื่อง) "โปรดให้คำแนะนำกับฉันและขอยกตัวอย่างให้ฉันอธิบาย" 2. "แต่คุณสามารถพูดได้ว่ามันเก็บวัตถุอีกเล็กน้อย .... " ฉันคิดว่า SOF ให้ตัวเลือกในการลงคะแนนและให้คำตอบใหม่ด้วย
Sabya

14

นี้บทความจะมีประโยชน์สุดที่จะเข้าใจแข็งแรงนุ่มอ่อนแอและผีอ้างอิง


เพื่อให้คุณสรุป

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

หากคุณมีข้ออ้างอิงที่อ่อนแอไปยังวัตถุ (โดยไม่มีการอ้างอิงที่แข็งแกร่ง) ดังนั้น GC จะเรียกคืนวัตถุในรอบ GC ถัดไป

หากคุณมีการอ้างอิงที่นุ่มนวลไปยังวัตถุ (โดยไม่มีการอ้างอิงที่รัดกุม) วัตถุนั้นจะถูกเรียกคืนโดย GC เฉพาะเมื่อ JVM มีหน่วยความจำไม่เพียงพอ

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


ดังนั้นคุณสามารถพูดได้ว่าการอ้างอิงที่แข็งแกร่งมีพลังอำนาจสูงสุด (ไม่สามารถรวบรวมได้โดย GC)

ซอฟท์อ้างอิงมีประสิทธิภาพมากกว่าการอ้างอิงที่อ่อนแอ (เพราะพวกเขาสามารถหลบหนีวงจร GC จนกระทั่ง JVM หมดหน่วยความจำ)

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


ร้านอาหารคล้ายคลึง

  • พนักงานเสิร์ฟ - GC
  • คุณ - วัตถุในกอง
  • พื้นที่ร้านอาหาร / พื้นที่ - พื้นที่กอง
  • ลูกค้าใหม่ - วัตถุใหม่ที่ต้องการโต๊ะในร้านอาหาร

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

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

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


10

4 องศาอ้างอิง - Strong, Weak, Soft, Phantom

Strong - เป็นการอ้างอิงชนิดหนึ่งซึ่งทำให้ออบเจ็กต์ที่อ้างอิงไม่มีสิทธิ์ใช้ GC เรียนสร้าง เช่น - StringBuilder

Weak - เป็นข้อมูลอ้างอิงที่มีสิทธิ์ได้รับ GC

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

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

การใช้งาน:

  1. ช่วยให้คุณระบุเมื่อวัตถุถูกลบออกจากหน่วยความจำอย่างแน่นอน

  2. เมื่อfinalize()เมธอดโอเวอร์โหลดดังนั้น GC อาจไม่เกิดขึ้นตามเวลาที่เหมาะสมสำหรับออบเจ็กต์ที่มีสิทธิ์ GC ของสองคลาส ดังนั้นการอ้างอิงแบบ phantom ทำให้พวกเขามีสิทธิ์ได้รับ GC ก่อนหน้าfinalize()นี้คือเหตุผลที่คุณสามารถรับOutOfMemoryErrorsได้แม้ว่าฮีปส่วนใหญ่จะเป็นขยะ

การอ้างอิงที่อ่อนแอเหมาะอย่างยิ่งสำหรับการนำโมดูลแคชไปใช้


10

การอ้างอิงที่แข็งแกร่ง

นี่คือการอ้างอิงวัตถุปกติของคุณซึ่งเราใช้รหัสทุกวัน:

Employee emp = new Employee();

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

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

ข้อมูลอ้างอิงที่อ่อนแอ

การอ้างอิงแบบอ่อนจะไม่ตรึงวัตถุไว้ในหน่วยความจำและจะเป็น GC'd ในวัฏจักร GC ถัดไปหากไม่ได้อ้างอิงจากการอ้างอิงอื่น เราสามารถใช้คลาส WeakReference ซึ่งจัดทำโดย Java เพื่อสร้างแคชด้านบนซึ่งจะไม่เก็บวัตถุที่ไม่ได้อ้างอิงจากที่อื่น

WeakReference<Cache> cache = new WeakReference<Cache>(data);

ในการเข้าถึงข้อมูลคุณต้องโทรไปที่ cache.get () การเรียกเพื่อรับนี้อาจส่งคืน null หากการอ้างอิงที่อ่อนแอคือการรวบรวมขยะ: คุณต้องตรวจสอบค่าที่ส่งคืนเพื่อหลีกเลี่ยง NPE Java มีคอลเลกชันที่ใช้การอ้างอิงที่อ่อนแอเช่นคลาส WeakHashMap จะเก็บคีย์ (ไม่ใช่ค่า) เป็นการอ้างอิงที่อ่อนแอ หากคีย์เป็น GC'd ค่าจะถูกลบออกจากแผนที่โดยอัตโนมัติเช่นกัน

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

อ้างอิงอ่อน

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

อ้างอิงผี

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

แล้วมันมีประโยชน์อย่างไร? เมื่อคุณสร้างการอ้างอิงแบบแฝงคุณต้องผ่านใน ReferenceQueue เสมอ สิ่งนี้บ่งชี้ว่าคุณสามารถใช้การอ้างอิงแฝงเพื่อดูว่าวัตถุของคุณเป็น GC'd หรือไม่

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

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับบทความของฉันประเภทของการอ้างอิงในชวา (แรง, ซอฟท์, อ่อนแอ, ผี)


คุณเขียนว่า refrences ที่อ่อนแอจะถูก GC'ed ในรอบต่อไปหากไม่ refrenced จาก refrences อื่น ๆ ... แต่ไม่ควรเกิดขึ้นในสิ่งเดียวกันกับ refrences stron? หากไม่ได้รับการตอบโต้แบบใด ๆ จากนั้นจะได้รับการล้าง ... ถ้าเป็นเช่นนั้นแล้วจะมีความแตกต่างอยู่ที่ไหน #confused
filemonczyk

1
หากวัตถุได้รับการอ้างอิงจากสมมุติว่า s1 (strong) และ s2 (strong) วัตถุนั้นจะไม่ได้รับสิทธิ์ในการรวบรวมขยะจนกว่าทั้ง s1 และ s2 จะถูกปฏิเสธ แต่ถ้าวัตถุนั้นถูกเรียกจาก s1 (อ่อนแอ) และ s2 ( strong) จากนั้น object จะมีสิทธิ์สำหรับการรวบรวมขยะในรอบ GC ถัดไปเมื่อได้รับการปฏิเสธจาก s2 เท่านั้นเนื่องจาก s1 เป็นการอ้างอิงที่อ่อนแอและหากวัตถุนั้นไม่มีการอ้างอิงอื่น ๆ ยกเว้นที่อ่อนแอจะมีสิทธิ์ GC
Naresh Joshi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.