โดยสังเขป
การสรุปไม่ใช่เรื่องง่ายที่นักสะสมขยะจะจัดการ ใช้งานง่ายด้วยการนับการอ้างอิงอ้างอิง GC แต่ตระกูล GC นี้มักจะไม่สมบูรณ์ต้องการการรั่วไหลของหน่วยความจำที่ต้องชดเชยด้วยการกระตุ้นการทำลายล้างและการสรุปวัตถุและโครงสร้างบางอย่าง การติดตามขยะสะสมมีประสิทธิภาพมากขึ้น แต่พวกมันทำให้ยากที่จะระบุวัตถุที่จะสรุปและทำลายเมื่อเทียบกับการระบุหน่วยความจำที่ไม่ได้ใช้งานดังนั้นจึงต้องมีการจัดการที่ซับซ้อนมากขึ้นด้วยต้นทุนในเวลาและพื้นที่ การดำเนินการ
บทนำ
ฉันคิดว่าสิ่งที่คุณถามคือสาเหตุที่ภาษาที่รวบรวมขยะไม่ได้จัดการกับการทำลาย / การสรุปโดยอัตโนมัติภายในกระบวนการรวบรวมขยะตามที่ระบุไว้ในหมายเหตุ
ฉันพบว่าภาษาเหล่านี้ไม่ได้พิจารณาถึงความทรงจำเป็นอย่างยิ่งเพราะเป็นเพียงการจัดการทรัพยากรที่คุ้มค่า เกี่ยวกับซ็อกเก็ตตัวจัดการไฟล์สถานะแอปพลิเคชัน
ผมไม่เห็นด้วยกับการได้รับการยอมรับคำตอบที่ได้รับจาก kdbanman ในขณะที่ข้อเท็จจริงดังกล่าวมีความถูกต้องเป็นส่วนใหญ่ แต่มีอคติอย่างมากต่อการนับการอ้างอิงฉันไม่เชื่อว่าพวกเขาอธิบายสถานการณ์ที่ถูกร้องเรียนในคำถามอย่างถูกต้อง
ฉันไม่เชื่อว่าคำศัพท์ที่พัฒนาขึ้นในคำตอบนั้นเป็นปัญหามากและมีแนวโน้มที่จะสับสนมากขึ้น แท้จริงแล้วตามที่นำเสนอคำศัพท์ส่วนใหญ่จะถูกกำหนดโดยวิธีการเปิดใช้งานมากกว่าที่จะทำ ประเด็นก็คือในทุกกรณีมีความจำเป็นที่จะต้องจบวัตถุที่ไม่จำเป็นต้องใช้กับกระบวนการล้างข้อมูลอีกต่อไปและเพื่อเพิ่มทรัพยากรใด ๆ ก็ตามที่ใช้งานอยู่หน่วยความจำเป็นเพียงหนึ่งในนั้น ตามหลักการแล้วควรทำทุกอย่างโดยอัตโนมัติเมื่อไม่ใช้งานวัตถุอีกต่อไปโดยใช้ตัวรวบรวมขยะ ในทางปฏิบัติ GC อาจขาดหายไปหรือมีข้อบกพร่องและสิ่งนี้จะได้รับการชดเชยโดยการกระตุ้นอย่างชัดเจนโดยโปรแกรมการสรุปและการเรียกคืน
การทริกเกอร์โดยชัดแจ้งของโปรแกรมเป็นปัญหาเนื่องจากอาจทำให้ยากต่อการวิเคราะห์ข้อผิดพลาดในการเขียนโปรแกรมเมื่อวัตถุที่ยังใช้อยู่ถูกยกเลิกอย่างชัดเจน
ดังนั้นจึงเป็นการดีกว่าที่จะพึ่งพาการรวบรวมขยะอัตโนมัติเพื่อเรียกคืนทรัพยากร แต่มีสองประเด็น:
เทคนิคการรวบรวมขยะบางอย่างจะอนุญาตให้มีหน่วยความจำรั่วที่ป้องกันการเรียกคืนทรัพยากรอย่างเต็มรูปแบบ สิ่งนี้เป็นที่รู้จักกันดีสำหรับการนับการอ้างอิงอ้างอิง GC แต่อาจปรากฏขึ้นสำหรับเทคนิค GC อื่น ๆ เมื่อใช้บางองค์กรข้อมูลโดยไม่สนใจ (จุดไม่ได้กล่าวถึงที่นี่)
ในขณะที่เทคนิค GC อาจใช้ประโยชน์ได้ดีในการระบุทรัพยากรหน่วยความจำที่ไม่ได้ใช้อีกต่อไป แต่การปิดวัตถุที่อยู่ในนั้นอาจไม่ง่ายและทำให้เกิดปัญหาในการเรียกคืนทรัพยากรอื่น ๆ ที่ใช้โดยวัตถุเหล่านี้
ในที่สุดประเด็นสำคัญที่มักถูกลืมคือวงจร GC สามารถถูกกระตุ้นได้โดยสิ่งใด ๆ ไม่ใช่เพียงแค่หน่วยความจำไม่เพียงพอหากมีการให้ฮุกที่เหมาะสมและหากค่าใช้จ่ายของวงจร GC นั้นถือว่าคุ้มค่า ดังนั้นจึงเป็นเรื่องที่ดีที่จะเริ่ม GC เมื่อทรัพยากรประเภทใดขาดหายไป
การอ้างอิงนักสะสมขยะนับ
การนับการอ้างอิงเป็นเทคนิคการรวบรวมขยะที่ไม่สามารถจัดการกับวงจรได้อย่างถูกต้อง มันจะอ่อนแอในการทำลายโครงสร้างที่ล้าสมัยและเรียกคืนทรัพยากรอื่น ๆ เพียงเพราะอ่อนแอในการเรียกคืนหน่วยความจำ แต่ finalizers สามารถใช้งานได้ง่ายที่สุดด้วยการอ้างอิงการเก็บขยะนับ (GC) เนื่องจากการนับ ref- GC จะ reclaims โครงสร้างเมื่อจำนวนการอ้างอิงของมันลดลงถึง 0 ซึ่งเป็นที่อยู่ของมันรู้พร้อมกับประเภทของมันทั้งแบบคงที่ หรือแบบไดนามิก ดังนั้นจึงเป็นไปได้ที่จะเรียกคืนหน่วยความจำอย่างแม่นยำหลังจากใช้งาน finalizer ที่เหมาะสมและการเรียกซ้ำกระบวนการบนวัตถุที่ชี้ทั้งหมด (อาจผ่านขั้นตอนการสรุป)
โดยสรุปแล้วขั้นตอนสุดท้ายนั้นง่ายต่อการนำไปใช้กับ Ref Counting GC แต่ทนทุกข์ทรมานจาก "ความไม่สมบูรณ์" ของ GC นั้นเนื่องจากโครงสร้างวงกลมเพื่อให้แม่นยำในระดับเดียวกับที่หน่วยความจำได้รับการฟื้นฟู กล่าวอีกนัยหนึ่งเมื่อนับการอ้างอิงหน่วยความจำจะได้รับการจัดการอย่างไม่ดีเท่ากับทรัพยากรอื่น ๆเช่นซ็อกเก็ตการจัดการไฟล์เป็นต้น
แท้จริงRef นับ GC ไม่สามารถที่จะเรียกคืนบ่วงโครงสร้าง (ทั่วไป) อาจจะเห็นเป็นหน่วยความจำรั่ว คุณไม่สามารถคาดหวัง GC ทั้งหมดเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ ขึ้นอยู่กับอัลกอริทึม GC และข้อมูลโครงสร้างชนิดที่มีอยู่แบบไดนามิก (เช่นใน
GC แบบอนุรักษ์นิยม )
ติดตามนักสะสมขยะ
ตระกูล GC ที่มีประสิทธิภาพยิ่งขึ้นโดยไม่มีการรั่วไหลนั้นคือตระกูลการติดตามที่สำรวจส่วนต่างๆของหน่วยความจำเริ่มต้นจากตัวชี้รูตที่ระบุได้ดี ทุกส่วนของหน่วยความจำที่ไม่ได้เข้าชมในกระบวนการตรวจสอบนี้ (ซึ่งสามารถจริงจะย่อยสลายในรูปแบบต่างๆ แต่ฉันมีเพื่อลดความซับซ้อน) เป็นส่วนที่ไม่ได้ใช้หน่วยความจำที่สามารถเรียกคืนจึง1 นักสะสมเหล่านี้จะเรียกคืนส่วนหน่วยความจำทั้งหมดที่โปรแกรมไม่สามารถเข้าถึงได้ไม่ว่าจะทำอะไรก็ตาม มันเรียกคืนโครงสร้างแบบวงกลมและ GC ขั้นสูงขึ้นอยู่กับการเปลี่ยนแปลงของกระบวนทัศน์นี้บางครั้งมีความซับซ้อนสูง สามารถใช้ร่วมกับการนับการอ้างอิงในบางกรณีและชดเชยจุดอ่อน
ปัญหาคือใบแจ้งยอดของคุณ (ในตอนท้ายของคำถาม):
ภาษาที่เสนอการรวบรวมขยะอัตโนมัติดูเหมือนจะเป็นตัวเลือกที่สำคัญในการสนับสนุนการทำลายวัตถุ / การจัดทำขั้นสุดท้ายตามที่พวกเขารู้ด้วยความมั่นใจ 100% เมื่อวัตถุไม่ได้ใช้งานอีกต่อไป
เทคนิคไม่ถูกต้องสำหรับการติดตามตัวสะสม
สิ่งที่เป็นที่รู้จักกันด้วยความมั่นใจ 100% ว่าจะเป็นอะไรส่วนของหน่วยความจำไม่ได้อยู่ในการใช้งาน (แม่นยำยิ่งขึ้นก็ควรจะกล่าวว่าพวกเขาไม่สามารถเข้าถึงได้อีกต่อไปเพราะบางส่วนที่ไม่สามารถใช้งานได้ตามตรรกะของโปรแกรมจะยังคงใช้งานอยู่หากยังมีตัวชี้ที่ไร้ประโยชน์ต่อพวกเขาในโปรแกรม ข้อมูล.) แต่การประมวลผลต่อโครงสร้างที่เหมาะสมและมีความจำเป็นที่จะรู้ว่าสิ่งที่วัตถุที่ไม่ได้ใช้อาจได้รับการจัดเก็บไว้ในเหล่านี้ตอนนี้ชิ้นส่วนที่ไม่ได้ใช้ของหน่วยความจำ ไม่สามารถระบุได้จากสิ่งที่เป็นที่รู้จักของโปรแกรมเนื่องจากโปรแกรมไม่ได้เชื่อมต่อกับส่วนต่าง ๆ ของหน่วยความจำเหล่านี้อีกต่อไป
ดังนั้นหลังจากผ่านการรวบรวมขยะคุณจะเหลือเศษชิ้นส่วนของหน่วยความจำที่มีวัตถุที่ไม่ได้ใช้งานอีกต่อไป แต่มีวิธีที่จะไม่ทราบว่าวัตถุเหล่านี้คืออะไรเพื่อใช้การสรุปที่ถูกต้อง นอกจากนี้หากตัวติดตามการติดตามเป็นประเภท mark-and-sweep อาจเป็นไปได้ว่าบางส่วนของชิ้นส่วนอาจมีวัตถุที่ผ่านการสรุปใน GC Pass ก่อนหน้าแล้ว แต่ไม่ได้ใช้เนื่องจากเหตุผลในการแยกส่วน อย่างไรก็ตามสิ่งนี้สามารถจัดการได้โดยใช้การพิมพ์แบบขยายเพิ่มเติม
ในขณะที่นักสะสมง่ายๆจะเรียกคืนหน่วยความจำเหล่านี้โดยไม่ต้องกังวลใจต่อไปการทำขั้นตอนสุดท้ายจำเป็นต้องใช้รหัสผ่านเฉพาะเพื่อสำรวจหน่วยความจำที่ไม่ได้ใช้นั้นระบุวัตถุที่มีอยู่และใช้ขั้นตอนสุดท้าย แต่การสำรวจดังกล่าวจำเป็นต้องมีการกำหนดประเภทของวัตถุที่ถูกเก็บไว้ที่นั่นและการกำหนดประเภทนั้นจำเป็นต้องมีเพื่อใช้การสรุปที่เหมาะสมหากมี
ดังนั้นนั่นหมายถึงค่าใช้จ่ายเพิ่มเติมในเวลา GC (ผ่านพิเศษ) และอาจมีค่าใช้จ่ายหน่วยความจำเพิ่มเติมเพื่อให้ข้อมูลประเภทที่เหมาะสมพร้อมใช้งานในระหว่างการส่งผ่านด้วยเทคนิคที่หลากหลาย ค่าใช้จ่ายเหล่านี้อาจมีความสำคัญเนื่องจากมักจะต้องการสรุปวัตถุเพียงไม่กี่ชิ้นเท่านั้นในขณะที่เวลาและพื้นที่ด้านบนอาจเกี่ยวข้องกับวัตถุทั้งหมด
อีกประเด็นหนึ่งคือค่าโสหุ้ยเวลาและพื้นที่อาจเกี่ยวข้องกับการเรียกใช้โค้ดโปรแกรมไม่ใช่เฉพาะการประมวลผล GC
ฉันไม่สามารถให้คำตอบที่แม่นยำมากขึ้นโดยชี้ไปที่ปัญหาเฉพาะเพราะฉันไม่ทราบรายละเอียดของภาษาที่คุณระบุ ในกรณีของ C การพิมพ์เป็นปัญหาที่ยากมากที่นำไปสู่การพัฒนานักสะสมแบบอนุรักษ์นิยม ฉันเดาว่าจะมีผลกระทบต่อ C ++ เช่นกัน แต่ฉันไม่มีความเชี่ยวชาญใน C ++ ดูเหมือนว่าจะได้รับการยืนยันจาก Hans Boehmซึ่งได้ทำการวิจัยเกี่ยวกับ GC อนุรักษ์นิยมมาก Conservative GC ไม่สามารถเรียกคืนหน่วยความจำที่ไม่ได้ใช้ทั้งหมดอย่างเป็นระบบได้อย่างแม่นยำเนื่องจากอาจไม่มีข้อมูลประเภทที่แม่นยำกับข้อมูล ด้วยเหตุผลเดียวกันนี้จึงไม่สามารถใช้ขั้นตอนการสรุปอย่างเป็นระบบได้
ดังนั้นจึงเป็นไปได้ที่จะทำสิ่งที่คุณขอตามที่คุณรู้จากบางภาษา แต่มันไม่มาฟรี อาจมีค่าใช้จ่ายแม้ว่าคุณจะไม่ได้ใช้คุณสมบัติก็ตามทั้งนี้ขึ้นอยู่กับภาษาและการใช้งาน เทคนิคและการแลกเปลี่ยนที่แตกต่างกันสามารถนำมาพิจารณาเพื่อแก้ไขปัญหาเหล่านี้ได้ แต่นั่นอยู่นอกเหนือขอบเขตของคำตอบที่เหมาะสม
1 - นี่เป็นการนำเสนอที่เป็นนามธรรมของการติดตามการรวบรวม (รวมทั้งการคัดลอกและการทำเครื่องหมายและกวาด GC) สิ่งต่าง ๆ ตามประเภทของตัวติดตามการติดตามและการสำรวจส่วนที่ไม่ได้ใช้ของหน่วยความจำจะแตกต่างกันขึ้นอยู่กับว่า ใช้การกวาด
finalize
/destroy
เป็นเรื่องโกหก? ไม่มีการรับประกันว่าจะถูกประหารชีวิต และแม้ว่าคุณจะไม่ทราบว่าเมื่อใด (ได้รับการรวบรวมขยะอัตโนมัติ) และหากบริบทที่จำเป็นยังคงมีอยู่ (อาจถูกรวบรวมไปแล้ว) ดังนั้นจึงปลอดภัยกว่าที่จะตรวจสอบสถานะที่สอดคล้องในวิธีอื่นและอาจต้องการบังคับให้โปรแกรมเมอร์ทำเช่นนั้น