คำนำ
บทความนี้พยายามสำรวจการอ้างอิงที่อ่อนแอใน Java จากมุมมองของสิ่งที่ทำไมและวิธีการที่จะช่วยให้ทุกคนเข้าใจคำจำกัดความสถานการณ์การใช้งานขั้นพื้นฐานและวิธีการใช้งานของการอ้างอิงที่อ่อนแอใน Java
1. อะไร-คำพูดที่อ่อนแอคืออะไร?
การอ้างอิงที่อ่อนแอใน Java โดยเฉพาะอ้างถึง java.lang.ref.WeakReference<T> คลาส ก่อนอื่นดูเอกสารอย่างเป็นทางการอธิบาย:
การมีอยู่ของวัตถุอ้างอิงที่อ่อนแอไม่ได้ป้องกันวัตถุที่ชี้ไปที่การรีไซเคิลโดยนักสะสมขยะ การใช้งานที่พบบ่อยที่สุดของการอ้างอิงที่อ่อนแอคือการใช้การแมป Canonicalizing (เช่นตารางแฮช)
สมมติว่านักสะสมขยะตัดสินใจว่าวัตถุนั้นสามารถเข้าถึงได้อย่างอ่อนแอ ณ เวลาหนึ่งเวลา (นั่นคือจุดทั้งหมดในปัจจุบันเป็นข้อมูลอ้างอิงที่อ่อนแอ) นักสะสมขยะจะล้างการอ้างอิงที่อ่อนแอทั้งหมดไปยังวัตถุจากนั้นทำเครื่องหมายวัตถุที่สามารถเข้าถึงได้ ในเวลาเดียวกันหรือในภายหลังตัวเก็บขยะจะวางการอ้างอิงที่อ่อนแอที่เพิ่งล้างใหม่ลงในคิวอ้างอิงที่ระบุเมื่อสร้างวัตถุอ้างอิงที่อ่อนแอ
ในความเป็นจริงมีการอ้างอิงสี่ประเภทใน Java ซึ่งมาจากความแข็งแกร่งถึงอ่อนแอ: การอ้างอิงที่แข็งแกร่ง , การอ้างอิงที่อ่อนนุ่ม , การอ้างอิงที่อ่อนแอ และ การอ้างอิงเสมือนจริง
ด้านล่างเราแนะนำการอ้างอิงอื่น ๆ อีกสามครั้งนอกเหนือจากการอ้างอิงที่อ่อนแอ:
1. การอ้างอิงที่แข็งแกร่ง: โดยปกติการอ้างอิงที่เรากลับมาเมื่อเราสร้างวัตถุใหม่ผ่านใหม่เป็นข้อมูลอ้างอิงที่แข็งแกร่ง หากวัตถุสามารถเข้าถึงได้ผ่านชุดของการอ้างอิงที่แข็งแกร่งก็สามารถเข้าถึงได้อย่างมากมันจะไม่ถูกนำกลับมาใช้ใหม่
2. การอ้างอิงที่อ่อนนุ่ม: ความแตกต่างระหว่างการอ้างอิงที่อ่อนนุ่มและการอ้างอิงที่อ่อนแอคือถ้าวัตถุสามารถเข้าถึงได้โดยการอ้างอิงที่อ่อนแอมันจะถูกรีไซเคิลโดยไม่คำนึงว่าหน่วยความจำปัจจุบันเพียงพอหรือไม่ ดังนั้นการอ้างอิงที่อ่อนนุ่มจึง "แข็งแกร่ง" กว่าการอ้างอิงที่อ่อนแอ
3. การอ้างอิง Phantom: การอ้างอิงเสมือนเป็นข้อมูลอ้างอิงที่อ่อนแอที่สุดใน Java ดังนั้นมันอ่อนแอแค่ไหน? มันบอบบางมากที่เราไม่สามารถรับวัตถุอ้างอิงผ่านการอ้างอิงเสมือนจริง จุดประสงค์เดียวของการอ้างอิงเสมือนคือเมื่อวัตถุที่ชี้ไปที่การรีไซเคิลการอ้างอิงเสมือนจะถูกเพิ่มเข้าไปในคิวอ้างอิงและใช้เพื่อบันทึกว่าวัตถุที่ชี้ไปที่ได้รับการรีไซเคิล
2. ทำไม-ทำไมต้องใช้การอ้างอิงที่อ่อนแอ?
พิจารณาสถานการณ์ต่อไปนี้: ขณะนี้มีคลาส Product ที่แสดงถึงผลิตภัณฑ์ซึ่งออกแบบมาให้ไม่สามารถลดขนาดได้และในเวลานี้เราต้องการเพิ่มตัวเลขให้กับแต่ละผลิตภัณฑ์ ทางออกหนึ่งคือใช้ HashMap<Product, Integer> ดังนั้นปัญหามาถึง หากเราไม่ต้องการวัตถุ Product ที่มีอยู่ในหน่วยความจำอีกต่อไป (ตัวอย่างเช่นผลิตภัณฑ์นี้ได้รับการขาย) โดยสมมติว่าการอ้างอิงเป็น productA เราจะกำหนดค่าให้กับ productA เป็น null อย่างไรก็ตามในเวลานี้วัตถุ Product ชี้ไปที่ productA ในอดีตจะไม่ถูกนำกลับมาใช้ใหม่เพราะมันถูกอ้างอิงโดย HashMap อย่างเห็นได้ชัด ดังนั้นในกรณีนี้หากเราต้องการรีไซเคิลวัตถุ Product อย่างแท้จริงมันไม่เพียงพอที่จะกำหนดการอ้างอิงที่แข็งแกร่งให้กับ null และเราต้องลบรายการที่เกี่ยวข้องออกจาก HashMap เห็นได้ชัดว่าเราไม่ต้องการให้งาน "ลบไม่จำเป็นต้องมีรายการจาก HashMap " โดยตัวเราเองอีกต่อไป เราต้องการบอกตัวเก็บขยะ: เฉพาะ key ใน HashMap อ้างอิงวัตถุ Product วัตถุ Product ที่เกี่ยวข้องสามารถรีไซเคิลได้ เห็นได้ชัดว่าขึ้นอยู่กับคำจำกัดความก่อนหน้าของการอ้างอิงที่อ่อนแอโดยใช้การอ้างอิงที่อ่อนแอสามารถช่วยให้เราบรรลุเป้าหมายนี้ เราเพียงแค่ต้องใช้วัตถุอ้างอิงที่อ่อนแอที่ชี้ไปที่วัตถุ Product เป็น key ใน HashMap
3. วิธีการใช้การอ้างอิงที่อ่อนแออย่างไร?
นำสถานการณ์ที่แนะนำไว้ข้างต้นเป็นตัวอย่าง เราใช้วัตถุอ้างอิงที่อ่อนแอที่ชี้ไปที่วัตถุ Product เป็น key ของ HashMap และเพียงกำหนดวัตถุอ้างอิงที่อ่อนแอนี้เช่นนี้:
Product Producta = ผลิตภัณฑ์ใหม่ (... ); Weakreference <ductions> beakproducta = new beakreference <> (producta);
ตอนนี้หากมีการอ้างอิงวัตถุ weakProductA มันจะชี้ไปที่ productA วัตถุ Product ดังนั้นเราจะได้รับ productA วัตถุ Product ที่ชี้ไปที่ weakProduct ได้อย่างไร
มันง่ายมากเพียงแค่ต้องการรหัสต่อไปนี้:
ผลิตภัณฑ์ผลิตภัณฑ์ = beakproducta.get ();
ในความเป็นจริงสำหรับกรณีนี้ห้องสมุด Java Class ให้เรากับคลาส WeakHashMap การใช้คลาสนี้คีย์ของมันเป็นวัตถุอ้างอิงที่อ่อนแอตามธรรมชาติและเราไม่จำเป็นต้องห่อวัตถุดั้งเดิมด้วยตนเองอีกต่อไป ด้วยวิธีนี้เมื่อ productA กลายเป็น null (มันบ่งชี้ว่า Product ที่อ้างอิงไม่จำเป็นต้องมีอยู่ในหน่วยความจำอีกต่อไป) Product อ้างอิงที่อ่อนแอคือ weakProductA จากนั้นเห็นได้ชัดว่า Product Product ที่สอดคล้องกันนั้นอ่อนแอและสามารถติดต่อได้ในเวลานี้
4. คิวอ้างอิง
มาแนะนำแนวคิดของการอ้างถึงคิวสั้น ๆ ในความเป็นจริงคลาส WeakReference มีสองตัวสร้าง:
// สร้างการอ้างอิงที่อ่อนแอไปยังวัตถุที่กำหนดค่าอ้างอิง (การอ้างอิง t) // สร้างการอ้างอิงที่อ่อนแอไปยังวัตถุที่กำหนดและลงทะเบียนการอ้างอิงที่อ่อนแอไปยังคิวการอ้างอิงที่อ่อนแอ (อ้างอิง t, referenceQueue <? super t> q)
เราจะเห็นได้ว่าตัวสร้างที่สองมีพารามิเตอร์ของ Type ReferenceQueue โดยการให้พารามิเตอร์นี้เราจะลงทะเบียนวัตถุอ้างอิงที่อ่อนแอที่สร้างขึ้นบนคิวอ้างอิง ด้วยวิธีนี้เมื่อมันถูกล้างโดยนักสะสมขยะมันจะถูกส่งไปยังคิวอ้างอิงและเราสามารถจัดการวัตถุอ้างอิงที่อ่อนแอที่ทำความสะอาดเหล่านี้ในลักษณะที่เป็นเอกภาพ
5. สรุป
เนื้อหาของบทความนี้จบลงที่นี่ เนื่องจากระดับส่วนบุคคลที่ จำกัด จึงมีแง่มุมที่ไม่ถูกต้องหรือไม่ชัดเจนในการบรรยาย ฉันหวังว่าคุณจะชี้ให้เห็นได้ขอบคุณสำหรับการสนับสนุน Wulin.com