เหตุใดการเก็บขยะจึงกวาดกองเท่านั้น


28

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

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


21
"swap the heap" ปลอดภัยกว่า "whack the stack" ... :-)
Brian Knoblauch

คำตอบ:


62

เก็บขยะไม่สแกนสแต็ค - เพื่อดูว่าสิ่งที่อยู่ในกองกำลังถูกนำมาใช้ (ชี้ไป) โดยสิ่งที่อยู่บนสแต็ค

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

(มีระบบเช่น smalltalk ที่สแต็กเฟรมเป็นวัตถุชั้นหนึ่งที่เก็บอยู่ในกองและขยะที่เก็บรวบรวมเช่นวัตถุอื่น ๆ ทั้งหมด แต่นั่นไม่ใช่วิธีที่ได้รับความนิยมในปัจจุบัน JVM ของ Java และ CLR ของ Microsoft ใช้ฮาร์ดแวร์สแต็กและหน่วยความจำต่อเนื่อง .)


7
+1 สามารถเข้าถึงสแต็กได้อย่างเต็มที่ดังนั้นจึงไม่มีความรู้สึกที่จะกวาดมัน
วงล้อประหลาด

2
+1 ขอบคุณใช้โพสต์ 4 คำตอบที่ถูกต้อง ฉันไม่รู้ว่าทำไมคุณต้องพูดทุกอย่างในสแต็กว่า "ถือว่า" ใช้งานอยู่มันใช้งานมันอย่างน้อยก็ถึงความรู้สึกที่แข็งแกร่งเมื่อวัตถุกองยังใช้อยู่ - แต่มันเป็นของจริง คำตอบที่ดีมาก
psr

@psr เขาหมายความว่าทุกอย่างบนสแต็กสามารถเข้าถึงได้อย่างมากและไม่จำเป็นต้องรวบรวมจนกว่าวิธีการส่งคืน แต่ (RAII) ได้รับการจัดการอย่างชัดเจนแล้ว
ratchet freak

@ ratchetfreak - ฉันรู้ และฉันแค่หมายถึงคำว่า "พิจารณา" อาจไม่จำเป็นมันก็โอเคที่จะทำให้คำสั่งที่แข็งแกร่งโดยไม่ได้
psr

5
@psr: ฉันไม่เห็นด้วย "การพิจารณาว่ามีการใช้งาน" นั้นถูกต้องทั้งในส่วนของ stack และ heap ด้วยเหตุผลที่สำคัญมาก สิ่งที่คุณต้องการคือการทิ้งสิ่งที่จะไม่ถูกใช้อีกครั้ง สิ่งที่คุณทำคือการที่คุณทิ้งสิ่งที่ไม่สามารถเข้าถึงได้ คุณอาจมีข้อมูลที่เข้าถึงได้ซึ่งคุณไม่ต้องการ เมื่อข้อมูลนี้เติบโตขึ้นคุณมีหน่วยความจำรั่ว (ใช่พวกเขาเป็นไปได้แม้ในภาษา GC'ed ซึ่งแตกต่างจากที่หลายคนคิด) และหนึ่งอาจยืนยันว่าการรั่วไหลของสแต็กเกิดขึ้นเช่นกันตัวอย่างที่พบบ่อยที่สุดคือเฟรมสแต็กที่ไม่จำเป็นในโปรแกรมเรียกใช้แบบเรียกซ้ำโดยไม่กำจัดการเรียกหาง (เช่นบน JVM)
Blaisorblade

19

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

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

เราจะหลีกเลี่ยงค่าใช้จ่ายเหล่านี้ได้อย่างไร

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

แต่ถ้าเราได้แก้ปัญหาหลุมจากนั้นเราได้แก้ปัญหาการเก็บขยะมากเกินไป คุณมีบางอย่างในที่เก็บที่ยังมีชีวิตอยู่หรือไม่? ใช่. ทุกสิ่งได้รับการจัดสรรก่อนที่จะมีอายุอีกต่อไปหรือไม่? ใช่ - สมมติฐานนี้เป็นวิธีกำจัดความเป็นไปได้ของหลุม ดังนั้นสิ่งที่คุณต้องทำคือพูดว่า "การจัดสรรครั้งล่าสุดยังมีชีวิตอยู่หรือไม่" และคุณรู้ว่าทุกสิ่งมีชีวิตในที่เก็บข้อมูลนั้น

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

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

นั่นเป็นสาเหตุที่เรามีพูลชั่วคราวในสแต็กตั้งแต่แรก: เพราะมันเป็นวิธีที่ง่ายในการใช้วิธีการเปิดใช้งานโดยไม่ทำให้เกิดการจัดการหน่วยความจำผิด

(แน่นอนว่ายังมีค่าใช้จ่ายในการเก็บขยะที่หน่วยความจำอ้างอิงโดยอ้างอิงในเฟรมการเปิดใช้งานยังคงอยู่ที่นั่น)

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

C # 2.0 yield returnมีคุณลักษณะนี้ในรูปแบบของ วิธีการที่ให้ผลตอบแทนเป็นไปได้ที่จะเปิดใช้งานในภายหลัง - ครั้งต่อไปที่เรียกว่า MoveNext - และเมื่อสิ่งที่เกิดขึ้นไม่สามารถคาดการณ์ได้ ดังนั้นข้อมูลที่ตามปกติจะอยู่ในสแต็กสำหรับกรอบการเปิดใช้งานของบล็อกตัววนซ้ำจะถูกเก็บไว้ในกองแทนที่จะเป็นที่เก็บขยะเมื่อมีการรวบรวมตัวแจงนับ

ในทำนองเดียวกันคุณสมบัติ "async / await" ที่มาในรุ่นถัดไปของ C # และ VB จะช่วยให้คุณสร้างวิธีที่การเปิดใช้งาน "ผลตอบแทน" และ "ดำเนินต่อ" ที่จุดที่กำหนดไว้อย่างดีในระหว่างการดำเนินการของวิธีการ เนื่องจากเฟรมการเปิดใช้งานจะไม่ถูกสร้างและทำลายในลักษณะที่คาดการณ์ได้อีกต่อไปข้อมูลทั้งหมดที่เคยถูกเก็บไว้ในสแต็กจะต้องถูกเก็บไว้ในกอง

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


13

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

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


5
แต่ฮีปไม่ใช่ตำแหน่งของ "ข้อมูลอินสแตนซ์" พวกเขาสามารถอยู่ในกองเกินไป
svick

@svick ขึ้นอยู่กับภาษาของหลักสูตร Java สนับสนุนเฉพาะวัตถุที่จัดสรรฮีปและ Vala ค่อนข้างแยกความแตกต่างอย่างชัดเจนระหว่างการจัดสรรฮีป (คลาส) และการจัดสรรสแต็ก (โครงสร้าง)
ปุย

1
@fluffy: ภาษาเหล่านี้มี จำกัด มากคุณไม่สามารถสรุปได้ว่านี่เป็นการถือโดยทั่วไปเนื่องจากไม่มีภาษาใดถูกกำหนดไว้ล่วงหน้า
Matthieu M.

@MatthieuM นั่นคือจุดของฉัน
ปุย

@fluffy: เหตุใดจึงมีการจัดสรรคลาสใน heap ในขณะที่ structs ใน stack
Dark Templar

10

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


1
ไม่เพียง แต่จะถูกจัดสรรคืนในที่สุด 'แต่จะถูกยกเลิกการจัดสรรในเวลาที่เหมาะสม
Boris Yankov

3
  1. ขนาดของสิ่งเหล่านั้นสามารถคาดการณ์ได้ (ค่าคงที่ยกเว้นสแต็กและสแต็กมัก จำกัด อยู่เพียงไม่กี่ MB) และโดยทั่วไปจะมีขนาดเล็กมาก (อย่างน้อยเมื่อเทียบกับแอพพลิเคชั่นขนาดใหญ่หลายร้อย MB อาจจัดสรร)

  2. โดยทั่วไปวัตถุที่จัดสรรแบบไดนามิกจะมีกรอบเวลาขนาดเล็กที่สามารถเข้าถึงได้ หลังจากนั้นไม่มีทางที่พวกเขาจะสามารถอ้างอิงได้อีกเลย ตรงกันข้ามกับรายการในส่วนข้อมูลตัวแปรทั่วโลกและเช่น: บ่อยครั้งที่มีชิ้นส่วนของรหัสที่อ้างอิงพวกเขาโดยตรง (คิดconst char *foo() { return "foo"; }) โดยปกติโค้ดจะไม่เปลี่ยนแปลงดังนั้นการอ้างอิงจะอยู่ต่อไปและการอ้างอิงอื่นจะถูกสร้างขึ้นทุกครั้งที่มีการเรียกใช้ฟังก์ชัน (ซึ่งอาจเป็นเมื่อใดก็ได้เท่าที่คอมพิวเตอร์รู้ - เว้นแต่คุณจะแก้ปัญหาการหยุดพัก ) ดังนั้นคุณไม่สามารถเพิ่มหน่วยความจำส่วนใหญ่ได้เนื่องจากจะสามารถเข้าถึงได้เสมอ

  3. ในภาษาที่รวบรวมขยะจำนวนมากทุกสิ่งที่เป็นของโปรแกรมที่กำลังทำงานอยู่นั้นถูกจัดสรรเป็นฮีป ใน Python ไม่มีส่วนข้อมูลใด ๆ และไม่มีค่าการจัดสรรสแต็ก (มีการอ้างอิงว่าตัวแปรโลคัลอยู่และมี call stack แต่ไม่มีค่าในแง่เดียวกันกับintใน c) วัตถุทุกอย่างอยู่ในกอง


"ใน Python นั้นไม่มีส่วนข้อมูลใด ๆ " นี่ไม่ได้พูดจริงอย่างเคร่งครัด ไม่มีจริงและเท็จได้รับการจัดสรรในส่วนข้อมูลตามที่ฉันเข้าใจ: stackoverflow.com/questions/7681786/how-is-hashnone- คำนวณ
Jason Baker

@ JasonBaker: ค้นหาที่น่าสนใจ! มันไม่มีผลอะไรเลย มันเป็นรายละเอียดการใช้งานและ จำกัด เฉพาะวัตถุที่มีอยู่ภายใน นั่นคือไม่พูดถึงว่าวัตถุเหล่านั้นไม่ได้คาดว่าจะได้รับการ deallocated เคยในชีวิตของโปรแกรมต่อไปไม่ได้และนอกจากนี้ยังมีขนาดเล็กในขนาด (น้อยกว่า 32 ไบต์แต่ละฉันเดา)

@delnan อย่างที่ Eric Lippert ชอบที่จะชี้ให้เห็นสำหรับภาษาส่วนใหญ่การมีอยู่ของขอบเขตหน่วยความจำที่แยกต่างหากสำหรับสแต็กและฮีปคือรายละเอียดการใช้งาน คุณสามารถใช้ภาษาส่วนใหญ่ได้โดยไม่ต้องใช้สแต็คเลย (แม้ว่าประสิทธิภาพอาจลดลงเมื่อคุณทำ) และยังสอดคล้องกับข้อกำหนดของภาษาเหล่านั้น
Jules

2

ตามที่มีผู้ตอบอีกจำนวนหนึ่งกล่าวว่าสแต็กเป็นส่วนหนึ่งของชุดรูทดังนั้นจึงมีการสแกนเพื่ออ้างอิง แต่ไม่ใช่ "รวบรวม" ตามลำดับ

ฉันแค่ต้องการตอบกลับความคิดเห็นที่บ่งบอกว่าขยะในกองซ้อนนั้นไม่สำคัญ มันทำเพราะมันอาจทำให้ขยะบนฮีปมากกว่านั้นถูกพิจารณาว่าสามารถเข้าถึงได้ VM ที่มีมโนธรรมและนักเขียนคอมไพเลอร์ไม่ว่าจะว่างเปล่าหรือแยกส่วนที่ไม่ทำงานของสแต็กออกจากการสแกน IIRC, VMs บางตัวมีตารางการจับคู่พีซีในตารางเพื่อบิตแมปแบบสแตติก -liveness และอื่น ๆ เพียงลบสล็อตออก ฉันไม่ทราบว่าเทคนิคใดที่เป็นที่ต้องการในขณะนี้

ระยะหนึ่งใช้เพื่ออธิบายการพิจารณาเรื่องนี้โดยเฉพาะเป็นที่ปลอดภัยสำหรับพื้นที่


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

@Brian ที่จริงแล้วกำลังคิดเกี่ยวกับมันมากขึ้นสำหรับ VM ที่พิมพ์แล้วคุณต้องการอะไรแบบนั้นอยู่แล้วดังนั้นคุณสามารถกำหนดได้ว่าช่องใดที่อ้างอิงถึงจำนวนเต็มลอยและอื่น ๆ เกี่ยวกับการกระชับสแต็กดู "CONS ควร ไม่ใช่ข้อโต้แย้งของมัน "โดยเฮนรีเบเกอร์
Ryan Culpepper

การกำหนดประเภทสล็อตและตรวจสอบว่าพวกเขาใช้อย่างเหมาะสมสามารถและมักจะทำแบบคงที่ทั้งในเวลารวบรวม (สำหรับ VMs ใช้ bytecode ที่เชื่อถือได้) หรือเวลาในการโหลด (ที่ bytecode มาจากแหล่งที่ไม่น่าเชื่อถือเช่น Java)
Jules

1

ฉันขอชี้ให้เห็นความเข้าใจผิดพื้นฐานบางประการที่คุณและคนอื่น ๆ เข้าใจผิด:

"ทำไมการเก็บขยะจึงกวาดกองเท่านั้น?" มันเป็นอีกทางหนึ่ง เฉพาะนักสะสมขยะที่ง่ายที่สุดอนุรักษ์นิยมและช้าที่สุดเท่านั้นที่กวาดกองขยะ นั่นเป็นเหตุผลที่พวกเขาช้ามาก

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

เนื่องจากฮีปมีขนาดใหญ่กว่าสแต็กประมาณ 1,000 เท่าโดยทั่วไป GC สแกนแบบสแต็กจึงเร็วกว่ามาก ~ 15ms เทียบกับ 250ms บนฮีปขนาดปกติ เนื่องจากเป็นการคัดลอก (ย้าย) วัตถุจากที่หนึ่งไปยังอีกที่หนึ่งซึ่งส่วนใหญ่เรียกว่าตัวคัดลอกแบบกึ่งพื้นที่มันต้องการหน่วยความจำ 2x และดังนั้นจึงไม่สามารถใช้งานได้บนอุปกรณ์ขนาดเล็กมากเช่นโทรศัพท์ที่มีหน่วยความจำไม่มาก มันกะทัดรัดดังนั้นจึงเป็นมิตรกับแคชมากในภายหลังซึ่งแตกต่างจากสแกนเนอร์มาร์ค & กวาดแบบง่าย ๆ

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

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


คำถามดูเหมือนจะมีอะไรเพิ่มเติมเกี่ยวกับส่วนของหน่วยความจำที่ถูกเก็บขยะมากกว่าอัลกอริทึมการเก็บขยะโดยเฉพาะ ประโยคสุดท้ายโดยเฉพาะนัยว่า OP กำลังใช้ "sweep" เป็นคำพ้องทั่วไปสำหรับ "garbage collect" แทนที่จะเป็นกลไกเฉพาะในการใช้การรวบรวมขยะ เมื่อพิจารณาว่าคำตอบของคุณพบว่ามีเพียงนักเก็บขยะที่ง่ายที่สุดเท่านั้นที่เก็บขยะกองและนักสะสมขยะอย่างรวดเร็วแทนการรวบรวมขยะกองซ้อนและหน่วยความจำแบบคงที่ปล่อยให้กองเติบโตและเติบโตจนกว่าหน่วยความจำจะหมด
8bittree

ไม่คำถามนั้นเจาะจงมากและฉลาด คำตอบไม่เป็นเช่นนั้น Mark & ​​sweep ที่ช้าของ GC มีสองขั้นตอนขั้นตอนทำเครื่องหมายสแกนรากบนสแต็กและขั้นตอนการกวาดจะสแกนกอง การคัดลอกที่รวดเร็วของ GC มีเพียงหนึ่งเฟสสแกนสแต็ก ง่ายเหมือนที่ เนื่องจากไม่มีใครรู้ที่นี่เกี่ยวกับนักสะสมขยะที่เหมาะสมจึงจำเป็นต้องตอบคำถาม การตีความของคุณถูกปิดอย่างดุเดือด
rurban

0

มีการจัดสรรอะไรในสแต็ก? ตัวแปรโลคัลและที่อยู่ส่งคืน (ใน C) เมื่อฟังก์ชันส่งคืนตัวแปรโลคัลจะถูกยกเลิก มันไม่จำเป็นแม้กระทั่งเป็นอันตรายต่อการกวาดกอง

ภาษาแบบไดนามิกจำนวนมากและ Java หรือ C # ถูกนำไปใช้ในภาษาการเขียนโปรแกรมระบบบ่อยครั้งใน C คุณสามารถพูดได้ว่า Java ถูกนำไปใช้กับฟังก์ชั่น C และใช้ตัวแปรโลคอล C และดังนั้นตัวรวบรวมขยะของ Java

มีข้อยกเว้นที่น่าสนใจคือ: เก็บขยะโครงการไก่ไม่กวาดสแต็ค (ในทาง) เพราะการดำเนินงานของสแต็คใช้เป็นพื้นที่เก็บขยะรุ่นแรก: ดูไก่รูปแบบการออกแบบวิกิพีเดีย

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