จะบังคับให้ตัวรวบรวมขยะทำงานได้อย่างไร


147

ผู้สัมภาษณ์ถามฉันเกี่ยวกับสิ่งนี้ในวันนี้ ... มีคำตอบไหม?


3
คำถามนี้มีข้อมูลที่ดีเกี่ยวกับสาเหตุที่คุณไม่ควรทำเช่นนั้น: stackoverflow.com/questions/118633/…
Hans Olsson

1
ทำไมคุณถึงบอกแบบนี้
Andrew Collins

1
@Jason - ผู้สัมภาษณ์อาจไม่ต้องการฟังวิธีแก้ปัญหา แต่ควรได้รับความรู้และเหตุผลจากการทำแอนดรูว์จากนั้นคำถามนี้อาจจะสมเหตุสมผล
martinstoeckli

2
@martinstoeckli ยังคงเป็นคำถามที่น่ากลัว คนที่มีความรู้ในการสัมภาษณ์อย่างเคร่งเครียดจะไม่ทราบว่ามันเป็นคำถามที่หลอกลวงหรือคิดว่าจะให้ข้อมูลเพิ่มเติม จากนั้นคำถามก็ไม่ได้ช่วยให้ผู้สัมภาษณ์แยกความแตกต่างระหว่างคนที่มีความรู้หรือคนที่ไม่มีมัน ดังนั้นคำถามยังคงแย่มาก
James

2
"คุณบังคับให้มีการรวบรวมขยะเมื่อใด" ดูเหมือนคำถามสัมภาษณ์ที่ดีสำหรับฉัน ("ดี": ไม่มาก) ระดับเริ่มต้น: ฉันไม่รู้แล้ว ระดับกลาง: ไม่เลย ผู้เชี่ยวชาญ: เมื่อคุณเขียนการทดสอบการรั่วไหลของหน่วยความจำ
mikebridge

คำตอบ:


188

System.GC.Collect()บังคับให้ตัวเก็บขยะทำงาน ไม่แนะนำให้ใช้ แต่สามารถใช้ได้หากเกิดสถานการณ์


17
ทำไมถึงไม่แนะนำ
ลุค T โอไบรอัน

5
GC.Collect () มีราคาแพงในการทำงาน ไม่ควรทำเกินความจำเป็น รหัสสำหรับเมื่อมันควรจะเรียกว่าเขียนได้ดี ปกติแล้วคุณควรรวบรวมเฉพาะกรณีขอบพิเศษ stackoverflow.com/a/21961777/2710988
Brandon Barkley

186

ไม่แนะนำให้โทร gc อย่างชัดเจน แต่ถ้าคุณโทร

GC.Collect();
GC.WaitForPendingFinalizers();

มันจะเรียก GC อย่างชัดเจนตลอดรหัสของคุณไม่ลืมที่จะเรียกหลังจากGC.WaitForPendingFinalizers();GC.Collect()


14
WaitForPendingFinalizersไม่จำเป็นต้องให้ "ประสิทธิภาพที่ดีขึ้น": มันเพียงแค่บล็อกจนกว่าวัตถุทั้งหมดในคิวการสรุปจะได้รับการสรุป (วัตถุที่อาจจะมีการเรียกก่อนหน้านี้ไปที่Collectนั่น) หากคุณต้องการโอกาสสำหรับผู้ที่วัตถุที่จะเก็บแล้วคุณต้องอื่นโทรไปCollect หลังจากที่WaitForPendingFinalizersโทร
ลุ

2
เนื่องจากหนึ่งในไม่กี่เหตุผลที่ดีในการโทร gc.Collect เป็นความพยายามครั้งสุดท้ายในการเพิ่มทรัพยากรที่ไม่ได้ถูกกำจัดอย่างเหมาะสม WaitForPendingFinalizers จึงดูเหมือนเป็นขั้นตอนที่จำเป็น ไม่แน่ใจว่าวิธีปฏิบัติที่ดีที่สุดคืออะไรเพื่อหลีกเลี่ยงการโทร gc.Collect มากเกินไปในกรณีเช่นนี้ BTW ฉันสงสัยว่ามีเหตุผลทางเทคนิคหรือไม่ที่ gc.Collect 'มี' เพื่อโปรโมตรุ่นต่อ ๆ ไป? ดูเหมือนว่าจะมีประโยชน์มากกว่าที่จะมีคนอยู่หลายชั่วอายุคนเว้นแต่จะมีการจัดสรรสิ่งของมากพอในการพิสูจน์ว่ามันก้าวหน้า
supercat

2
หมายเหตุสำหรับผู้เริ่มต้นใน C # (เช่นฉัน): การเรียกใช้การบังคับ GC ไม่รับประกันวัตถุที่ไม่ได้ใช้งานบางอย่างจะถูกลบออกจากหน่วยความจำ (วิธีหนึ่งในการทำเช่นนี้คือการใช้ "การใช้คำสั่ง" ( msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx ))
user1234567

ทำไมมันควรจะเป็นสิ่งสำคัญที่จะโทรWaitForPendingFinalizers?
คริสเตียน

19
GC.Collect() 

จากMDSN ,

ใช้วิธีนี้เพื่อพยายามเรียกคืนหน่วยความจำทั้งหมดที่ไม่สามารถเข้าถึงได้

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



12

GC.Collect();

อย่างไรก็ตามโปรดจำไว้ว่าตัวรวบรวมขยะอาจไม่ล้างสิ่งที่คุณคาดหวังเสมอ ...


5
คุณหมายถึงอะไร? ทำความสะอาดโดยไม่คาดหมายอะไร
โวลเดอมอ

5
@Voldemort - มันจะไม่ทำความสะอาดอะไรเลย แต่อาจไม่ล้างทุกอย่างที่คุณคาดหวัง
Justin Niessner

6

คุณไม่ต้องการบังคับให้ตัวรวบรวมขยะทำงาน

อย่างไรก็ตามถ้าคุณเคยทำ (เป็นแบบฝึกหัดทางวิชาการอย่างแท้จริง):

GC.Collect()

4
ฉันชอบคำตอบของ @ Karthik อาจมีสถานการณ์ที่แอปควรเรียก GC.Collect () อย่างถูกกฎหมาย แม้ว่าจะไม่ค่อยมาก
Henk Holterman

2
สมมติว่าคุณมีข้อมูลอ้างอิงที่อ่อนแอและต้องการตรวจสอบว่ามีการอ้างอิงใดที่ 'สด' อยู่หรือไม่ มันสมเหตุสมผลแล้วที่จะเรียก GC.Collect () ก่อนตรวจสอบ แค่พูด.
คนรวยอีเมอร์

1
ลดลงเนื่องจากคำสั่งเปิดไม่ถูกต้องตามข้อเท็จจริง ใช่ฉันต้องการบังคับให้ตัวรวบรวมขยะทำงาน
Syndog

5

ฉันคิดว่า. Net Framework ทำสิ่งนี้โดยอัตโนมัติ แต่ในกรณี ขั้นแรกตรวจสอบให้แน่ใจว่าได้เลือกสิ่งที่คุณต้องการลบแล้วเรียกตัวเก็บรวบรวมขยะ:

randomClass object1 = new randomClass
...
...
// Give a null value to the code you want to delete
object1 = null;
// Then call the garbage collector to erase what you gave the null value
GC.Collect();

ฉันคิดว่ามัน .. หวังว่าฉันจะช่วยใครบางคน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.