ความแตกต่างระหว่างjava.lang.ref.WeakReference
และjava.lang.ref.SoftReference
คืออะไร
ความแตกต่างระหว่างjava.lang.ref.WeakReference
และjava.lang.ref.SoftReference
คืออะไร
คำตอบ:
จากการทำความเข้าใจข้อมูลอ้างอิงที่อ่อนแอโดย Ethan Nicholas:
ข้อมูลอ้างอิงที่อ่อนแอ
การอ้างอิงที่อ่อนแอง่าย ๆ คือการอ้างอิงที่ไม่แข็งแรงพอที่จะบังคับให้วัตถุยังคงอยู่ในหน่วยความจำ การอ้างอิงที่อ่อนแอช่วยให้คุณสามารถใช้ความสามารถของตัวเก็บขยะเพื่อกำหนดความสามารถในการเข้าถึงสำหรับคุณดังนั้นคุณไม่จำเป็นต้องทำเอง คุณสร้างการอ้างอิงที่อ่อนแอเช่นนี้:
WeakReference weakWidget = new WeakReference(widget);
และที่อื่นในรหัสคุณสามารถใช้
weakWidget.get()
รับWidget
วัตถุจริง แน่นอนการอ้างอิงที่อ่อนแอยังไม่แข็งแรงพอที่จะป้องกันการรวบรวมขยะดังนั้นคุณอาจพบ (หากไม่มีการอ้างอิงที่รัดกุมในวิดเจ็ต) ที่weakWidget.get()
เริ่มส่งคืนnull
ทันที...
อ้างอิงอ่อน
การอ้างอิงที่นุ่มนวลเป็นเหมือนการอ้างอิงที่อ่อนแอยกเว้นว่ามันมีความกระตือรือร้นน้อยกว่าที่จะโยนวัตถุที่มันอ้างอิง วัตถุที่เข้าถึงได้ง่ายเพียงเล็กน้อย (การอ้างอิงที่แข็งแกร่งที่สุดคือ
WeakReferences
) จะถูกยกเลิกในรอบการรวบรวมขยะครั้งถัดไป แต่วัตถุที่เข้าถึงได้อย่างนุ่มนวลโดยทั่วไปจะติดอยู่ครู่หนึ่ง
SoftReferences
ไม่จำเป็นต้องทำตัวแตกต่างไปจากเดิมWeakReferences
แต่โดยทั่วไปแล้ววัตถุที่เข้าถึงได้อย่างนุ่มนวลจะถูกเก็บรักษาไว้ตราบเท่าที่หน่วยความจำมีอยู่มากมาย สิ่งนี้ทำให้พวกเขาเป็นรากฐานที่ยอดเยี่ยมสำหรับแคชเช่นแคชรูปภาพที่อธิบายไว้ข้างต้นเนื่องจากคุณสามารถปล่อยให้ตัวรวบรวมขยะกังวลเกี่ยวกับว่าวัตถุที่เข้าถึงได้นั้นเป็นอย่างไร (วัตถุที่เข้าถึงได้สูงจะไม่ถูกลบออกจากแคช) ต้องการหน่วยความจำที่พวกเขากำลังบริโภค
และ Peter Kessler เพิ่มในความคิดเห็น:
Sun JRE ปฏิบัติ SoftReferences ต่างจาก WeakReferences เราพยายามที่จะยึดวัตถุที่อ้างอิงโดย SoftReference หากไม่มีแรงกดดันต่อหน่วยความจำที่มีอยู่ รายละเอียดหนึ่ง: นโยบายสำหรับ "-client" และ "-server" JRE นั้นแตกต่างกัน: -client JRE พยายามรักษารอยเท้าของคุณให้เล็กลงโดยเลือกที่จะล้าง SoftReferences แทนการขยายฮีปในขณะที่ -verver JRE พยายามที่จะทำให้คุณ ประสิทธิภาพสูงโดยเลือกที่จะขยายฮีป (ถ้าเป็นไปได้) แทนที่จะล้าง SoftReferences ขนาดเดียวไม่พอดีทั้งหมด
การอ้างอิงที่อ่อนแอจะถูกรวบรวมอย่างกระตือรือร้น หาก GC พบว่าวัตถุนั้นสามารถเข้าถึงได้อย่างอ่อน (เข้าถึงได้จากการอ้างอิงที่อ่อนแอเท่านั้น) มันจะล้างการอ้างอิงที่อ่อนแอไปยังวัตถุนั้นทันที เช่นนี้จะเป็นการดีสำหรับการอ้างอิงถึงวัตถุที่โปรแกรมของคุณเก็บไว้ (อ้างอิงอย่างยิ่ง) "ข้อมูลที่เกี่ยวข้อง" ซึ่งเป็นที่อื่นเช่นการสะท้อนแคชที่เกี่ยวกับคลาสหรือ wrapper สำหรับวัตถุ ฯลฯ สิ่งใดก็ตามที่ทำให้ ไม่มีเหตุผลที่จะเก็บไว้หลังจากวัตถุที่เกี่ยวข้องกับนั้นคือ GC-ed เมื่อการอ้างอิงที่อ่อนแอได้รับการเคลียร์จะได้รับการจัดคิวในคิวการอ้างอิงที่รหัสของคุณสำรวจที่ไหนสักแห่งและมันจะทิ้งวัตถุที่เกี่ยวข้องเช่นกัน นั่นคือคุณเก็บข้อมูลเพิ่มเติมเกี่ยวกับวัตถุ แต่ไม่จำเป็นต้องใช้ข้อมูลนั้นเมื่อวัตถุที่อ้างถึงหายไป อันที่จริงแล้ว ในบางสถานการณ์คุณยังสามารถคลาสย่อย WeakReference และเก็บข้อมูลพิเศษที่เกี่ยวข้องเกี่ยวกับวัตถุในฟิลด์ของคลาสย่อย WeakReference การใช้งานทั่วไปของ WeakReference ร่วมกับแผนที่เพื่อรักษาอินสแตนซ์แบบบัญญัติ
ในทางกลับกัน SoftReferences นั้นดีสำหรับการแคชภายนอกทรัพยากรที่สามารถกู้คืนได้เนื่องจาก GC โดยทั่วไปจะเลื่อนการล้างออกไป มีการรับประกันว่า SoftReferences ทั้งหมดจะถูกล้างก่อนที่ OutOfMemoryError จะถูกโยนดังนั้นพวกเขาจึงไม่สามารถทำให้ OOME [*] ตามหลักวิชาได้
ตัวอย่างกรณีการใช้งานทั่วไปคือการเก็บรูปแบบการแยกวิเคราะห์เนื้อหาจากไฟล์ คุณจะใช้ระบบที่คุณจะโหลดไฟล์แยกวิเคราะห์และเก็บ SoftReference ให้กับวัตถุรูทของการแทนคำ ครั้งต่อไปที่คุณต้องการไฟล์คุณจะพยายามดึงไฟล์ผ่าน SoftReference หากคุณสามารถเรียกคืนได้คุณจะได้รับภาระ / การแยกวิเคราะห์อีกครั้งและหาก GC ลบออกในระหว่างนั้นคุณจะโหลดซ้ำ ด้วยวิธีนี้คุณใช้หน่วยความจำฟรีเพื่อเพิ่มประสิทธิภาพ แต่ไม่เสี่ยงต่อ OOME
ตอนนี้สำหรับ [*] การรักษา SoftReference ไม่สามารถทำให้ OOME อยู่ในตัวได้ หากในทางตรงกันข้ามคุณใช้ SoftReference โดยไม่ตั้งใจสำหรับงาน WeakReference นั้นควรใช้ (กล่าวคือคุณเก็บข้อมูลที่เกี่ยวข้องกับวัตถุที่อ้างอิงอย่างใดอย่างหนึ่งและทิ้งไว้เมื่อวัตถุอ้างอิงได้รับการเคลียร์) คุณสามารถเรียกใช้เป็น OOME เป็น รหัสของคุณที่โพล ReferenceQueue และทิ้งวัตถุที่เกี่ยวข้องอาจเกิดขึ้นไม่ทำงานในเวลาที่เหมาะสม
ดังนั้นการตัดสินใจขึ้นอยู่กับการใช้งาน - หากคุณแคชข้อมูลที่มีราคาแพงในการสร้าง แต่ยังสร้างขึ้นใหม่จากข้อมูลอื่น ๆ ให้ใช้การอ้างอิงแบบนุ่มนวล - หากคุณทำการอ้างอิงกับอินสแตนซ์มาตรฐานของข้อมูลบางส่วนหรือคุณต้องการ มีการอ้างอิงไปยังวัตถุโดยไม่มี "เป็นเจ้าของ" มัน (ดังนั้นการป้องกันไม่ให้มันเป็น GC'd) ให้ใช้การอ้างอิงที่อ่อนแอ
WeakReference
คือในสถานที่ที่ควรใช้งานความจริงที่ว่าหนึ่งอาจยังคงใช้งานได้เพียงเล็กน้อยในขณะที่หลังจากการอ้างอิงไปนอกขอบเขตอาจจะทนได้ แต่ไม่พึงประสงค์
WeakReference
คือสังเกตการทำงานของ GC ดูรายละเอียดเพิ่มเติมได้ที่: stackoverflow.com/a/46291143/632951
ใน Java ; สั่งซื้อจากที่แข็งแกร่งถึงที่อ่อนแอที่สุดมี: ที่แข็งแกร่งนุ่มที่อ่อนแอและผี
การอ้างอิงที่แข็งแกร่งคือการอ้างอิงปกติที่ปกป้องวัตถุที่อ้างอิงจากการรวบรวมโดย GC นั่นคือไม่เคยเก็บขยะ
การอ้างอิงแบบนุ่มมีสิทธิ์ได้รับการรวบรวมโดยตัวรวบรวมขยะ แต่อาจจะไม่ถูกรวบรวมจนกว่าจะต้องใช้หน่วยความจำ OutOfMemoryError
เก็บรวบรวมขยะเช่นก่อน
การอ้างอิงที่อ่อนแอเป็นการอ้างอิงที่ไม่ได้ป้องกันวัตถุที่อ้างอิงจากการรวบรวมโดย GC เช่นขยะเก็บรวบรวมเมื่อไม่มีการอ้างอิงที่แข็งแกร่งหรืออ่อน
การอ้างอิง Phantomเป็นการอ้างอิงไปยังวัตถุที่มีการอ้างอิง phantomly หลังจากที่ได้รับการสรุป แต่ก่อนที่หน่วยความจำที่จัดสรรไว้ได้รับการเรียกคืน
การเปรียบเทียบ:สมมติว่า JVM เป็นอาณาจักรวัตถุเป็นกษัตริย์ของอาณาจักรและ GC เป็นผู้โจมตีของราชอาณาจักรที่พยายามฆ่ากษัตริย์ (วัตถุ)
until memory is available
ไม่สมเหตุสมผล คุณหมายถึงis eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use
อะไร
การอ้างอิงที่อ่อนแอ http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
หลักการ: weak reference
เกี่ยวข้องกับการเก็บขยะ โดยปกติวัตถุที่มีอย่างน้อยหนึ่งรายการreference
จะไม่มีสิทธิ์ได้รับการรวบรวมขยะ หลักการข้างต้นไม่บังคับเมื่อมันเป็น
weak reference
หากวัตถุมีการอ้างอิงที่อ่อนแอกับวัตถุอื่นเท่านั้นแสดงว่าพร้อมสำหรับการรวบรวมขยะ
ลองดูตัวอย่างด้านล่าง: เรามีMap
กับวัตถุที่สำคัญคือการอ้างอิงวัตถุ
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> aMap = new
HashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
System.out.println("Size of Map" + aMap.size());
}
}
emp = null
ตอนนี้ในระหว่างการทำงานของโปรแกรมที่เราได้ทำ การMap
ถือกุญแจนั้นไม่สมเหตุสมผลnull
เลย ในสถานการณ์ข้างต้นวัตถุไม่ได้เก็บรวบรวมขยะ
WeakHashMap
WeakHashMap
เป็นหนึ่งในสถานที่ที่รายการ ( key-to-value mappings
) Map
จะถูกลบออกเมื่อมันเป็นไปไม่ได้ที่จะดึงพวกเขาออกจาก
ให้ฉันแสดงตัวอย่างข้างต้นเช่นเดียวกันกับWeakHashMap
import java.util.WeakHashMap;
public class Test {
public static void main(String args[]) {
WeakHashMap<Employee, EmployeeVal> aMap =
new WeakHashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
int count = 0;
while (0 != aMap.size()) {
++count;
System.gc();
}
System.out.println("Took " + count
+ " calls to System.gc() to result in weakHashMap size of : "
+ aMap.size());
}
}
ผลลัพธ์:ใช้20 calls to System.gc()
ผลลัพธ์เป็นaMap size
: 0
WeakHashMap
มีเพียงการอ้างอิงที่อ่อนแอไปยังคีย์ไม่ใช่การอ้างอิงที่แข็งแกร่งเช่นMap
คลาสอื่น ๆ WeakHashMap
มีสถานการณ์ที่คุณต้องดูแลเมื่อค่าหรือคีย์มีการอ้างอิงอย่างยิ่งว่าคุณได้ใช้เป็น นี้สามารถหลีกเลี่ยงได้โดยการตัดวัตถุในWeakReference
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> map =
new HashMap<Employee, EmployeeVal>();
WeakReference<HashMap<Employee, EmployeeVal>> aMap =
new WeakReference<HashMap<Employee, EmployeeVal>>(
map);
map = null;
while (null != aMap.get()) {
aMap.get().put(new Employee("Vinoth"),
new EmployeeVal("Programmer"));
System.out.println("Size of aMap " + aMap.get().size());
System.gc();
}
System.out.println("Its garbage collected");
}
}
อ้างอิงอ่อน
Soft Reference
มีความแข็งแกร่งเล็กน้อยที่อ้างอิงอ่อนแอ การอ้างอิงแบบนุ่มช่วยให้สามารถรวบรวมขยะได้ แต่ขอให้ผู้รวบรวมขยะทำการล้างเฉพาะในกรณีที่ไม่มีตัวเลือกอื่น
ตัวรวบรวมขยะไม่ได้รวบรวมวัตถุที่เข้าถึงได้อย่างเบา ๆ อย่างที่มันทำกับวัตถุที่เข้าถึงได้ง่าย แต่จะรวบรวมเฉพาะวัตถุที่เข้าถึงได้อย่างนุ่มนวลหากหน่วยความจำต้องการ การอ้างอิงอย่างนุ่มนวลเป็นวิธีการพูดกับตัวเก็บขยะ "ตราบใดที่หน่วยความจำไม่แน่นเกินไปฉันก็อยากจะเก็บวัตถุนี้ไว้รอบ ๆ แต่ถ้าหน่วยความจำแน่นจริงๆให้ไปข้างหน้าและรวบรวมมันแล้วฉันจะจัดการ กับสิ่งนั้น " ตัวรวบรวมขยะจำเป็นต้องเคลียร์การอ้างอิงแบบอ่อนทั้งหมดก่อนที่จะสามารถโยนOutOfMemoryError
ได้
NullPointerException
aMap.get().put(...)
WeakHashMap
ตัวอย่าง (เนื่องจากเป็นตัวอย่างแรกที่แสดงให้เห็นถึงพฤติกรรมที่อ่อนแอ) ดูเอกสารสำหรับ "WeakHashMap": "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. "
จุดทั้งหมดของการใช้ WeakHashMap คือคุณไม่ต้องประกาศ / ส่งผ่าน WeakReference WeakHashMap ทำเพื่อคุณภายใน docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
WeakHashMap
การทำงานพร้อมแอพตัวอย่างที่แสดงให้เห็นว่ารายการจะถูกลบออกได้อย่างไรหลังจากเรียกใช้งานคอลเลกชันขยะดูคำตอบสำหรับคำถามของฉันWeakHashMap เติบโตขึ้นเรื่อย ๆ หรือไม่หรือลบคีย์ขยะออก .
ความแตกต่างที่แท้จริงเพียงอย่างเดียวระหว่างการอ้างอิงแบบนุ่มนวลและการอ้างอิงแบบอ่อนคือ
ตัวรวบรวมขยะใช้อัลกอริทึมในการตัดสินใจว่าจะเรียกคืนวัตถุที่สามารถเข้าถึงได้อย่างนุ่มนวลหรือไม่ แต่จะเรียกคืนวัตถุที่สามารถเข้าถึงได้อย่างอ่อนอยู่เสมอ
SoftReference
ถูกออกแบบมาสำหรับแคช เมื่อพบว่ามีWeakReference
การอ้างอิงวัตถุที่ไม่สามารถเข้าถึงได้มิฉะนั้นจะถูกลบทันที SoftReference
อาจถูกทิ้งไว้ตามที่เป็นอยู่ โดยทั่วไปจะมีอัลกอริทึมที่เกี่ยวข้องกับจำนวนหน่วยความจำที่ว่างและเวลาที่ใช้ล่าสุดเพื่อตรวจสอบว่าควรจะล้าง อัลกอริทึม Sun ปัจจุบันคือการล้างข้อมูลอ้างอิงหากไม่ได้ใช้งานในไม่กี่วินาทีเนื่องจากมีหน่วยความจำเมกะไบต์ฟรีบน Java heap (กำหนดค่าได้ HotSpot เซิร์ฟเวอร์จะตรวจสอบกับ heap ที่เป็นไปได้สูงสุดตามที่กำหนดโดย-Xmx
) SoftReference
s จะถูกล้างก่อนที่OutOfMemoryError
จะถูกโยนเว้นแต่จะเข้าถึงได้เป็นอย่างอื่น
java.lang
ของตัวเองไม่ได้ การใช้คำพ้องความหมายดังกล่าวเป็นการกระทำที่ไม่ดี
นี้บทความจะมีประโยชน์สุดที่จะเข้าใจแข็งแรงนุ่มอ่อนแอและผีอ้างอิง
เพื่อให้คุณสรุป
หากคุณมีการอ้างอิงอ่อนไปยังวัตถุ (โดยไม่มีการอ้างอิงที่แข็งแกร่ง) ดังนั้น GC จะเรียกคืนวัตถุในรอบ GC ถัดไป
หากคุณมีการอ้างอิงที่นุ่มนวลไปยังวัตถุ (โดยไม่มีการอ้างอิงที่รัดกุม) วัตถุนั้นจะถูกเรียกคืนโดย GC เฉพาะเมื่อ JVM มีหน่วยความจำไม่เพียงพอ
ดังนั้นคุณสามารถพูดได้ว่าการอ้างอิงที่แข็งแกร่งมีพลังอำนาจสูงสุด (ไม่สามารถรวบรวมได้โดย GC)
ซอฟท์อ้างอิงมีประสิทธิภาพมากกว่าการอ้างอิงที่อ่อนแอ (เพราะพวกเขาสามารถหลบหนีวงจร GC จนกระทั่ง JVM หมดหน่วยความจำ)
การอ้างอิงที่อ่อนแอนั้นมีประสิทธิภาพน้อยกว่าการอ้างอิงแบบนุ่มนวล (เนื่องจากไม่สามารถ excape รอบ GC ใด ๆ และจะถูกเรียกคืนหากวัตถุไม่มีการอ้างอิงที่แข็งแกร่งอื่น ๆ )
ร้านอาหารคล้ายคลึง
ตอนนี้ถ้าคุณเป็นลูกค้าที่แข็งแกร่ง (คล้ายกับการอ้างอิงที่แข็งแกร่ง) ถึงแม้ว่าลูกค้าใหม่เข้ามาในร้านอาหารหรือสิ่งที่เคยมีความสุขคุณจะไม่ออกจากโต๊ะของคุณ (พื้นที่หน่วยความจำบนกอง) พนักงานเสิร์ฟไม่มีสิทธิ์บอกคุณ (หรือแม้แต่ขอให้คุณ) ออกจากร้านอาหาร
หากคุณเป็นลูกค้าที่อ่อนนุ่ม (คล้ายกับการอ้างอิงที่อ่อนนุ่ม) ดังนั้นหากมีลูกค้าใหม่เข้ามาในร้านอาหารพนักงานเสิร์ฟจะไม่ขอให้คุณออกจากโต๊ะเว้นแต่จะไม่มีโต๊ะว่างเหลืออยู่เพื่อรองรับลูกค้าใหม่ (กล่าวอีกนัยหนึ่งพนักงานเสิร์ฟจะขอให้คุณออกจากโต๊ะเฉพาะเมื่อมีลูกค้าใหม่เข้ามาและไม่มีโต๊ะเหลือสำหรับลูกค้าใหม่นี้)
หากคุณเป็นลูกค้าที่อ่อนแอ (คล้ายกับการอ้างอิงที่อ่อนแอ) พนักงานเสิร์ฟตามความประสงค์ของเขาสามารถ (เมื่อใดก็ได้) ขอให้คุณออกจากร้านอาหาร: P
ต่อเอกสารจะต้องทำการล้างWeakReferences ที่หลวมโดย GC ที่กำลังรันอยู่
ตามเอกสารจะต้องล้างSoftReferences ที่หลวมก่อนที่จะมีการโยน OOM
นั่นคือความแตกต่างที่แท้จริงเท่านั้น ทุกอย่างอื่นไม่ได้เป็นส่วนหนึ่งของสัญญา (ฉันจะถือว่าเอกสารล่าสุดเป็นสัญญา)
SoftReferences มีประโยชน์ แคชที่ไวต่อหน่วยความจำใช้ SoftReferences ไม่ใช่ WeakReferences
weak_ref.get()
ออกจาก เมื่อเป็นnull
เช่นนั้นคุณจะได้เรียนรู้ว่าระหว่างช่วงเวลานี้ GC ทำงาน
สำหรับการใช้ WeakReference ที่ไม่ถูกต้องรายการจะไม่มีที่สิ้นสุด:
แฮ็คที่น่าสงสารที่จะใช้ซอฟต์เรนเดอร์ลำดับความสำคัญ -2 ซึ่งคุณไม่ต้องเขียนแต่มันก็ไม่ได้ผลอย่างที่คาดไว้เพราะแคชจะถูกล้างในทุกการรันของ GC แม้ว่าจะมีหน่วยความจำสำรอง ดู https://stackoverflow.com/a/3243242/632951สำหรับ phails (นอกจากนี้แล้วถ้าคุณต้องการลำดับความสำคัญแคชมากกว่า 2 ระดับคุณจะต้องมีไลบรารี่จริงด้วย)
แฮ็คหมัดเพื่อเชื่อมโยงข้อมูลกับวัตถุของคลาสที่มีอยู่แต่มันสร้างหน่วยความจำรั่ว (OutOfMemoryError) เมื่อ GC ของคุณตัดสินใจที่จะหยุดพักหลังจากสร้างจุดอ่อนของคุณ นอกจากนี้มันเกินกว่าน่าเกลียด: วิธีที่ดีกว่าคือการใช้สิ่งอันดับ
แฮ็คหมัดเพื่อเชื่อมโยงข้อมูลกับวัตถุของคลาสที่มีอยู่ซึ่งคลาสมีเส้นประสาทที่ทำให้ตัวเองไม่สามารถจัดประเภทย่อยได้และใช้ในโค้ดฟังก์ชันที่มีอยู่ซึ่งคุณต้องโทรหา ในกรณีเช่นนี้ทางออกที่เหมาะสมคือแก้ไขคลาสและทำให้คลาสย่อยหรือแก้ไขฟังก์ชั่นและทำให้ใช้อินเตอร์เฟสแทนคลาสหรือใช้ฟังก์ชันทางเลือก
equals()
เป็นเพียงตัวตนของวัตถุ? การอ้างอิงที่นุ่มนวลดูเหมือนของเสียที่นั่นเพราะเมื่อวัตถุสำคัญไม่สามารถเข้าถึงได้อีกต่อไปไม่มีใครที่จะค้นหาการทำแผนที่นั้นอีกครั้ง
สถานะการเข้าถึงวัตถุหกชนิดใน Java:
สำหรับรายละเอียดเพิ่มเติม: https://www.artima.com/insidejvm/ed2/gc16.html «ยุบ
เราควรทราบว่าวัตถุที่อ้างอิงอย่างอ่อนจะได้รับการรวบรวมเมื่อมันมีการอ้างอิงที่อ่อนแอเท่านั้น ถ้ามันมีการอ้างอิงที่รัดกุมมาก ๆ มันจะไม่ได้รับการรวบรวมไม่ว่าจะมีการอ้างอิงที่อ่อนแอเท่าใด
เพื่อให้การใช้งานหน่วยความจำแบบแอ็คชั่นฉันได้ทำการทดลองกับการอ้างอิงแบบ Strong, Soft, Weak & Phantom ภายใต้การใช้งานจำนวนมากที่มีวัตถุหนักโดยการเก็บไว้จนถึงตอนท้ายของโปรแกรม จากนั้นตรวจสอบการใช้งานกองและพฤติกรรม GC ตัวชี้วัดเหล่านี้อาจแตกต่างกันไปในแต่ละกรณี แต่ให้ความเข้าใจในระดับสูงอย่างแน่นอน ด้านล่างนี้เป็นข้อค้นพบ
Heap & GC Behavior ภายใต้ภาระหนัก
คุณสามารถรับกราฟเชิงลึกสถิติการสังเกตการณ์สำหรับการทดสอบนี้ได้มากขึ้นที่นี่
WeakReference : วัตถุที่อ้างอิงอย่างอ่อนเท่านั้นจะถูกรวบรวมในทุก ๆ รอบของ GC (เล็กน้อยหรือเต็ม)
SoftReference : เมื่อรวบรวมวัตถุที่มีการอ้างอิงอย่างนุ่มนวลเท่านั้นจะถูกรวบรวมขึ้นอยู่กับ:
-XX: SoftRefLRUPolicyMSPerMB = N แฟล็ก (ค่าเริ่มต้นคือ 1,000, aka 1 วินาที)
จำนวนหน่วยความจำว่างในกอง
ตัวอย่าง:
จากนั้นวัตถุที่ถูกอ้างอิงโดย SoftReference เท่านั้นจะถูกรวบรวมหากครั้งล่าสุดที่มีการเข้าถึงมากกว่า 10 วินาที