เหตุใดภาษาเช่น C และ C ++ จึงไม่มีการรวบรวมขยะในขณะที่ Java ทำ [ปิด]


57

ฉันรู้ว่ามีหลายอย่างเช่น malloc / free สำหรับ C และใหม่ / using-a-destructor สำหรับการจัดการหน่วยความจำใน C ++ แต่ฉันสงสัยว่าทำไมไม่มี "การอัพเดทใหม่" สำหรับภาษาเหล่านี้ที่ทำให้ผู้ใช้ มีตัวเลือกในการจัดการหน่วยความจำด้วยตนเองหรือสำหรับระบบที่จะทำโดยอัตโนมัติ (เก็บขยะ)?

ค่อนข้างเป็นคำถามที่แปลกใหม่ แต่อยู่ใน CS ประมาณ 1 ปีเท่านั้น


9
เรามีโมดูลในการพัฒนา iPhone ภาคการศึกษานี้ หลังจากเขียนรหัสแอพสำหรับ Android เป็นเวลา 2 ปีคำถามนี้ทำให้คนส่วนใหญ่เรียนยาก ตอนนี้เราเห็นว่ากี่ชั่วโมง Java ได้ช่วยเราจริงๆโดยไม่ต้องติดตามข้อผิดพลาดในการจัดการหน่วยความจำที่น่ารังเกียจและไม่ต้องเขียนรหัสแผ่นหม้อน้ำ
siamii

7
@NullUserException เนื่องจากไม่ได้ระบุวิธีในการเรียกคืนหน่วยความจำที่มีความหมายถึง GC
Winston Ewert

1
@ bizso09: คุณดู ARC หรือยัง ไม่จำเป็นต้องใช้ GC แบบช้า / อ้วน / แบบไม่กำหนดค่าเมื่อคุณได้รับการสนับสนุนจากระบบสำหรับการอ้างอิง: developer.apple.com/technologies/ios5
JBRWilkinson

3
คำตอบสำหรับคำถามที่ดีงามนี้เต็มไปด้วยเรื่องไร้สาระทางศาสนา
abatishchev

1
ใน C และ C ++ เป็นไปได้ที่จะใช้พอยน์เตอร์, ส่งมันไปที่ int และเพิ่มตัวเลขเข้าไป ในภายหลังย่อจำนวนจาก int และส่งผลลัพธ์กลับไปยังตัวชี้ คุณจะได้รับพอยน์เตอร์เหมือนเดิม ขอให้โชคดีในการใช้งาน GC ซึ่งไม่ได้เก็บหน่วยความจำนั้นในขณะที่ที่อยู่ถูกเก็บไว้ในตัวแปรที่มีค่าอื่นอยู่ด้วย ฉันรู้ว่าตัวอย่างนั้นโง่ แต่รายการที่ลิงก์ XORใช้สิ่งที่คล้ายกัน ฉันจะโพสต์สิ่งนี้เป็นคำตอบ แต่คำถามถูกปิด
Marian Spanik

คำตอบ:


72

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

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


26
ปัญหารองคือ GC ไม่สามารถกำหนดได้ วัตถุอาจอยู่ในหน่วยความจำหรือไม่นานหลังจากที่โปรแกรม "ทำ" มันหายไป วงจรชีวิตการนับซ้ำนั้นกำหนดขึ้นเมื่อการอ้างอิงครั้งสุดท้ายถูกทิ้งหน่วยความจำจะถูกทิ้ง สิ่งนี้มีความหมายไม่เพียง แต่สำหรับประสิทธิภาพของหน่วยความจำ แต่สำหรับการดีบั๊กเช่นกัน ข้อผิดพลาดทั่วไปในการเขียนโปรแกรมคือวัตถุ "zombie" ซึ่งเป็นหน่วยความจำอ้างอิงที่ทิ้งไว้ในทางทฤษฎี GC มีแนวโน้มที่จะปกปิดเอฟเฟกต์นี้ได้มากขึ้นและสร้างบั๊กที่ไม่ต่อเนื่องและยากต่อการติดตาม
kylben

22
- gc ที่ทันสมัยไม่มีการจัดสรรแทร็กหรือนับการอ้างอิง พวกเขาสร้างกราฟจากทุกสิ่งที่อยู่ในสแต็กในปัจจุบันและเพียงแค่ย่อและล้างทุกอย่าง (แบบง่าย) และโดยทั่วไป GC จะลดความซับซ้อนของภาษาลง แม้แต่ประสิทธิภาพการทำงานก็ยังเป็นที่น่าสงสัย
Joel Coehoorn

13
เอ่อ, @ kylben, จุดทั้งหมดของการอบ GC อัตโนมัติเป็นภาษานั้นมันเป็นไปไม่ได้ที่จะอ้างอิงวัตถุซอมบี้, เพราะ GC จะปลดปล่อยเฉพาะวัตถุที่ไม่สามารถอ้างอิงได้! คุณได้รับการเรียงลำดับของข้อบกพร่องที่ยากต่อการติดตามที่คุณกำลังพูดถึงเมื่อคุณทำผิดพลาดกับการจัดการหน่วยความจำด้วยตนเอง
Ben

14
-1, GC จะไม่นับการอ้างอิง ยิ่งไปกว่านั้นขึ้นอยู่กับการใช้งานหน่วยความจำและรูปแบบการจัดสรรของคุณ GC จะเร็วขึ้น (โดยมีการใช้หน่วยความจำมากเกินไป) ดังนั้นข้อโต้แย้งเกี่ยวกับประสิทธิภาพจึงเป็นความเข้าใจผิดเช่นกัน เฉพาะจุดที่ใกล้กับโลหะเท่านั้นที่เป็นจุดที่ถูกต้องจริง
deadalnix

14
ทั้ง Java หรือ C # การอ้างอิงใช้การนับ: แผนการ GC ขึ้นอยู่กับการนับการอ้างอิงจะสวยดั้งเดิมในการเปรียบเทียบและดำเนินการมากยิ่งกว่าการสะสมขยะที่ทันสมัย (ส่วนใหญ่เป็นเพราะพวกเขาต้องทำหน่วยความจำเขียนที่จะปรับเปลี่ยนการนับจำนวนการอ้างอิงเมื่อใดก็ตามที่คุณคัดลอกอ้างอิง!)
mikera

44

พูดอย่างเคร่งครัดไม่มีการจัดการหน่วยความจำเลยในภาษา C malloc () และ free () ไม่ใช่คำหลักในภาษา แต่เป็นเพียงฟังก์ชั่นที่ถูกเรียกจากไลบรารี ความแตกต่างนี้อาจเป็นความอวดรู้ในขณะนี้เนื่องจาก malloc () และ free () เป็นส่วนหนึ่งของไลบรารีมาตรฐาน C และจะได้รับจากการดำเนินการตามมาตรฐาน C ใด ๆ แต่สิ่งนี้ไม่ได้เกิดขึ้นจริงในอดีต

ทำไมคุณต้องการภาษาที่ไม่มีมาตรฐานสำหรับการจัดการหน่วยความจำ สิ่งนี้จะกลับไปที่ต้นกำเนิดของ C เป็น 'ชุดประกอบแบบพกพา' มีหลายกรณีของฮาร์ดแวร์และอัลกอริทึมที่สามารถได้รับประโยชน์จากหรือแม้กระทั่งต้องการเทคนิคการจัดการหน่วยความจำแบบพิเศษ เท่าที่ฉันรู้ไม่มีทางปิดการใช้งานการจัดการหน่วยความจำดั้งเดิมของ Java อย่างสมบูรณ์และแทนที่ด้วยตัวคุณเอง สิ่งนี้ไม่เป็นที่ยอมรับในบางสถานการณ์ที่มีประสิทธิภาพสูง / สถานการณ์ทรัพยากรน้อยที่สุด C ให้ความยืดหยุ่นเกือบสมบูรณ์ในการเลือกโครงสร้างพื้นฐานที่โปรแกรมของคุณจะใช้ ราคาที่จ่ายคือภาษา C ให้ความช่วยเหลือน้อยมากในการเขียนรหัสที่ถูกต้องและไม่มีบั๊ก


2
+1 หนึ่งสำหรับคำตอบที่ดีโดยรวม แต่ยังโดยเฉพาะอย่างยิ่งสำหรับ "ราคาที่จ่ายคือภาษา C ให้ความช่วยเหลือน้อยมากในการเขียนที่ถูกต้องข้อผิดพลาดรหัสฟรี"
Shivan มังกร

2
C มีการจัดการหน่วยความจำ - แต่ใช้งานได้ดังนั้นผู้คนแทบจะไม่สังเกตเห็น มีหน่วยความจำแบบคงที่ลงทะเบียนและสแต็ค จนกว่าคุณจะเริ่มจัดสรรจากกองคุณก็โอเคและสวย เป็นการจัดสรรฮีพที่ทำให้เกิดความยุ่งเหยิง สำหรับ Java ทุกคนสามารถเขียน Java runtime ได้เองมีให้เลือกมากมายรวมถึงสิ่งที่เรียกว่า "System's Java" .NET สามารถทำได้ทุกอย่างที่ C ทำได้ - มันช้ากว่าความสามารถดั้งเดิมของ C ++ เท่านั้น (เช่นคลาสมีการจัดการเฉพาะใน. NET) แน่นอนคุณมี C ++. NET ซึ่งมีทุกอย่างที่ C ++ ทำและทุกอย่างที่ NET ทำ
Luaan

1
@ Luaan ฉันจะบอกว่ามันเป็นคำจำกัดความที่ดีมากของการมี "การจัดการหน่วยความจำ" "จนกว่าคุณจะเริ่มจัดสรรจากกองคุณเป็นคนดีและมีฝีมือมันคือการจัดสรรกองที่ทำให้สิ่งต่าง ๆ ยุ่งเหยิง" นั่นก็เหมือนกับการพูดว่ารถยนต์คือ เครื่องบินที่ดีอย่างสมบูรณ์มันไม่สามารถบินได้
Charles E. Grant

1
@ CharlesE.Grant ภาษาที่ใช้งานได้ดีสามารถทำทุกอย่างได้ด้วยการจัดการหน่วยความจำแบบนั้น เพียงเพราะการจัดสรรฮีปเป็นการแลกเปลี่ยนที่ดีในบางกรณีการใช้งานไม่ได้หมายความว่ามันเป็นมาตรฐานสำหรับทุกภาษา / รันไทม์ มันไม่เหมือนการจัดการหน่วยความจำที่หยุด "การจัดการหน่วยความจำ" เพียงเพราะมันง่ายตรงไปตรงมาซ่อนอยู่เบื้องหลัง การออกแบบการจัดสรรหน่วยความจำแบบสแตติกยังคงเป็นการจัดการหน่วยความจำเช่นเดียวกับการใช้งานสแต็กที่ดีและสิ่งอื่นที่คุณมี
Luaan

"การใช้งานที่เป็นไปตามมาตรฐาน" ไม่เป็นความจริงเพียงอย่างเดียวสำหรับการปรับใช้สภาพแวดล้อมโฮสต์ที่ได้มาตรฐาน บางแพลตฟอร์ม / มาตรฐาน Librarys ส่วนใหญ่สำหรับ 8 หรือ 16 บิตฝังไมโครคอนโทรลเลอร์ไม่ให้หรือmalloc() free()(ตัวอย่างคือ MLAP-Compilers สำหรับ PIC)
12431234123412341234123

32

คำตอบที่แท้จริงคือวิธีเดียวที่จะทำให้กลไกการรวบรวมขยะที่ปลอดภัยและมีประสิทธิภาพคือการสนับสนุนระดับภาษาสำหรับการอ้างอิงทึบแสง (หรือตรงกันข้ามขาดการสนับสนุนระดับภาษาสำหรับการจัดการหน่วยความจำโดยตรง)

Java และ C # สามารถทำได้เนื่องจากมีประเภทการอ้างอิงพิเศษที่ไม่สามารถจัดการได้ สิ่งนี้ให้อิสระในการทำสิ่งต่าง ๆ เช่นการย้ายวัตถุที่ถูกจัดสรรในหน่วยความจำซึ่งมีความสำคัญต่อการใช้งาน GC ที่มีประสิทธิภาพสูง

สำหรับเร็กคอร์ดไม่มีการใช้งาน GC ที่ทันสมัยใช้การนับการอ้างอิงเพื่อให้เป็นปลาเฮอริ่งแดงอย่างสมบูรณ์ GCs สมัยใหม่ใช้คอลเลคชั่น generational ซึ่งการจัดสรรใหม่จะได้รับการปฏิบัติเป็นหลักเช่นเดียวกับการจัดสรรสแต็คในภาษาเช่น C ++ และจากนั้นวัตถุที่ได้รับการจัดสรรใหม่เป็นระยะ ๆ จะถูกย้ายไปยังพื้นที่ "ผู้รอดชีวิต" แยกต่างหาก ของวัตถุถูกยกเลิกการจัดสรรในครั้งเดียว

วิธีนี้มีข้อดีข้อเสีย: ข้อเสียคือการจัดสรรฮีปในภาษาที่สนับสนุน GC นั้นเร็วพอ ๆ กับการจัดสรรสแต็กในภาษาที่ไม่รองรับ GC และข้อเสียคือวัตถุที่ต้องล้างข้อมูลก่อนที่จะถูกทำลาย ต้องการกลไกแยกต่างหาก (เช่นusingคีย์เวิร์ดของ C # ) มิฉะนั้นโค้ดการล้างข้อมูลของมันจะทำงานแบบไม่กำหนดค่า

โปรดทราบว่าหนึ่งกุญแจสำหรับ GC ประสิทธิภาพสูงคือต้องมีการสนับสนุนภาษาสำหรับการอ้างอิงระดับพิเศษ C ไม่มีการสนับสนุนภาษานี้และจะไม่; เนื่องจาก C ++ มีตัวดำเนินการมากไปมันอาจเลียนแบบตัวชี้ GC'd ได้แม้ว่ามันจะต้องทำอย่างระมัดระวัง ในความเป็นจริงเมื่อ Microsoft คิดค้นภาษา C ++ ที่จะทำงานภายใต้ CLR (รันไทม์. NET) พวกเขาจะต้องสร้างไวยากรณ์ใหม่สำหรับ "C # -style reference" (เช่นFoo^) เพื่อแยกพวกเขาออกจาก "C ++ - การอ้างอิงลักษณะ" (เช่นFoo&)

สิ่งที่ C ++ มีและสิ่งที่โปรแกรม C ++ ใช้เป็นประจำคือพอยน์เตอร์อัจฉริยะซึ่งเป็นเพียงกลไกการนับการอ้างอิง ฉันจะไม่พิจารณาการนับการอ้างอิงว่าเป็น "จริง" GC แต่มันให้ประโยชน์มากมายเหมือนกันในราคาที่ประสิทธิภาพช้ากว่าการจัดการหน่วยความจำด้วยตนเองหรือ GC จริง แต่ก็มีข้อดีของการทำลายล้างที่กำหนดขึ้น

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


4
นี่คือคำตอบที่แท้จริงสำหรับคำถาม
coredump

1
สำหรับส่วน c ++ ทุกวันนี้คุณควรดู std :: unique_ptr และ std :: move :)
Niclas Larsson

@NiclasLarsson: ฉันไม่แน่ใจว่าฉันเข้าใจประเด็นของคุณ คุณกำลังพูดว่านั่นstd::unique_ptrคือ "การสนับสนุนระดับภาษาสำหรับการอ้างอิงทึบแสง" หรือไม่? (มันไม่ใช่การสนับสนุนที่ฉันหมายถึงและฉันก็คิดว่าไม่เพียงพอถ้าการสนับสนุนสำหรับการจัดการหน่วยความจำโดยตรงถูกลบออกจาก C ++ ด้วย) ฉันพูดถึงตัวชี้อัจฉริยะในคำตอบของฉันและฉันจะพิจารณาstd:unique_ptrตัวชี้อัจฉริยะ เนื่องจากจริง ๆ แล้วทำการนับการอ้างอิงมันสนับสนุนเฉพาะกรณีพิเศษที่จำนวนการอ้างอิงเป็นศูนย์หรือหนึ่ง (และstd::moveเป็นกลไกการปรับปรุงการนับจำนวนการอ้างอิง)
Daniel Pryden

std::unique_ptrไม่มีการนับการอ้างอิงและstd::moveไม่มีส่วนเกี่ยวข้องกับการอ้างอิงเลย (ดังนั้นจึงไม่มีผลการทำงานที่ "ไม่") ผมเห็นจุดของคุณ แต่เป็นstd::shared_ptrจะมีจำนวนการอ้างอิงที่ implicity ปรับปรุงโดยstd::move:)
Niclas ลาร์สสัน

2
@ Mike76: ในด้านการจัดสรรผู้จัดสรร GC จะทำงานได้เร็วเท่ากับการจัดสรรสแต็กและ GC สามารถจัดสรรคืนวัตถุหลายพันรายการในเวลาเดียวกัน ไม่ว่าสิ่งที่คุณทำกับโทษ-นับการดำเนินการจัดสรรและ deallocation จะไม่เร็วกว่าและmalloc freeดังนั้นใช่ GC สามารถเร็วขึ้นอย่างมาก (โปรดทราบว่าฉันพูดว่า "สามารถ" - แน่นอนประสิทธิภาพที่แน่นอนของแต่ละโปรแกรมได้รับผลกระทบจากปัจจัยหลายอย่าง)
Daniel Pryden

27

เพราะเมื่อใช้พลังของ C ++ ไม่จำเป็นต้องใช้

สมุนไพรซัทเทอร์: " ฉันยังไม่ได้เขียนลบในปี "

ดูการเขียนรหัส C ++ ที่ทันสมัย: วิธีการที่ C ++ มีวิวัฒนาการในช่วงหลายปีที่ผ่านมา 21:10

อาจทำให้โปรแกรมเมอร์ C ++ มีประสบการณ์มากมาย


น่าสนใจ ฉันอ่านเนื้อหาสำหรับวันนี้
surfasb

Bah, วิดีโอ แต่ไม่น้อยที่น่าสนใจแล้ว
surfasb

2
วิดีโอที่น่าสนใจ 21 นาทีและ 55 นาทีเป็นบิตที่ดีที่สุด น่าเสียดายที่การโทร WinRT ยังคงดูเหมือนว่าจะเป็น C ++ / CLI bumpf
gbjbaanb

2
@ dan04: จริง แต่ถ้าคุณเขียนเป็น C คุณจะได้สิ่งที่คุณขอ
DeadMG

6
การจัดการพอยน์เตอร์อัจฉริยะไม่ได้เรียกร้องมากไปกว่าการทำให้แน่ใจว่าคุณไม่มีการอ้างอิงที่ไม่จำเป็นในสภาพแวดล้อมที่เก็บขยะ เนื่องจาก GC ไม่สามารถอ่านใจของคุณได้
Tamás Szelei

15

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

มีการสะสมขยะที่เขียนขึ้นสำหรับ C และ C ++ มี - อันนี้ยกตัวอย่างเช่น

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


1
แต่โปรแกรมในอนาคตที่เขียนจะเริ่มใช้ตัวรวบรวมขยะใช่ไหม
Dark Templar

5
ในขณะที่การรวบรวมขยะนั้นมีความเป็นอิสระจากภาษาการเขียนโปรแกรมในทางทฤษฎีแล้วมันค่อนข้างยากที่จะเขียน GC ที่มีประโยชน์สำหรับ C / C ++ และแม้แต่เป็นไปไม่ได้ที่จะสร้างการพิสูจน์แบบโง่ ๆ off เป็นเพราะมันทำงานในสภาพแวดล้อมเสมือนจริงที่มีการควบคุม ในทางกลับกันภาษาจาวาได้รับการออกแบบสำหรับ GC และคุณจะมีเวลาในการเขียนคอมไพเลอร์ Java ที่ไม่ได้ทำใน GC
tdammers

4
@tdammers: ฉันยอมรับว่าจำเป็นต้องได้รับการสนับสนุนโดยการรวบรวมขยะในภาษา อย่างไรก็ตามประเด็นหลักไม่ใช่การจำลองเสมือนและการควบคุมสภาพแวดล้อม แต่เป็นการพิมพ์ที่เข้มงวด C และ C ++ พิมพ์อย่างอ่อนดังนั้นจึงอนุญาตให้สิ่งต่าง ๆ เช่นการจัดเก็บตัวชี้ในตัวแปรจำนวนเต็มการสร้างพอยน์เตอร์พอยน์เตอร์จากออฟเซ็ตและสิ่งต่าง ๆ ที่ป้องกันไม่ให้นักสะสมสามารถบอกได้ว่าสามารถเข้าถึงได้อย่างไร นักสะสมหัวโบราณ) ใน Java คุณจะรู้ว่าอะไรคือการอ้างอิงเพื่อให้คุณสามารถรวบรวมได้อย่างแม่นยำแม้ว่าจะรวบรวมเป็นภาษาพื้นเมือง
Jan Hudec

2
@ ThorbjørnRavnAndersen: ฉันสามารถเขียนโปรแกรม C ที่ถูกต้องที่เก็บพอยน์เตอร์ในลักษณะที่ไม่มีผู้รวบรวมขยะสามารถค้นหาพวกเขาได้ หากคุณขอให้ผู้รวบรวมขยะไปที่mallocและfreeคุณจะทำลายโปรแกรมที่ถูกต้องของฉัน
Ben Voigt

2
@ ThorbjørnRavnAndersen: ไม่ฉันจะไม่เรียกfreeจนกว่าฉันจะทำมันเสร็จ แต่ตัวรวบรวมขยะที่คุณเสนอซึ่งไม่ได้เพิ่มหน่วยความจำจนกว่าฉันfreeจะเรียกอย่างชัดเจนว่าไม่ใช่ตัวรวบรวมขยะ
Ben Voigt

12

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


9

ฉันไม่มีคำพูดที่แน่นอน แต่ทั้ง Bjarne และ Herb Sutter พูดอะไรบางอย่างตามสาย:

C ++ ไม่ต้องการตัวรวบรวมขยะเนื่องจากไม่มีขยะ

ใน C ++ ยุคปัจจุบันคุณใช้ตัวชี้อัจฉริยะและไม่มีขยะ


1
พอยน์เตอร์อัจฉริยะคืออะไร?
Dark Templar

11
ถ้ามันง่ายขนาดนั้นคงไม่มีใครนำ GC มาใช้เลย
deadalnix

7
@deadalnix: ถูกต้องเพราะไม่มีใครทำอะไรที่ซับซ้อนเกินไปช้าบวมหรือไม่จำเป็น ซอฟต์แวร์ทั้งหมดมีประสิทธิภาพ 100% ตลอดเวลาใช่ไหม
Zach

5
@deadalnix - วิธีการจัดการหน่วยความจำ C ++ นั้นใหม่กว่าตัวรวบรวมขยะ RAII ถูกคิดค้นโดย Bjarne Stroustrup สำหรับ C ++ การล้างข้อมูล Destructor เป็นแนวคิดที่เก่ากว่า แต่กฎในการสร้างความมั่นใจในข้อยกเว้นด้านความปลอดภัยคือกุญแจสำคัญ ฉันไม่รู้ว่าเมื่อไหร่ที่ความคิดของตัวเองถูกอธิบายครั้งแรก แต่มาตรฐาน C ++ ตัวแรกได้รับการสรุปในปี 1998 และ Stroustrups "การออกแบบและวิวัฒนาการของ C ++" ไม่ได้เผยแพร่จนถึงปี 1994 และข้อยกเว้นเป็นส่วนเสริมล่าสุดของ C ++ - หลังจากการตีพิมพ์ของ "คู่มืออ้างอิง C ++ หมายเหตุประกอบ" ในปี 1990 ฉันเชื่อว่า GC ถูกประดิษฐ์ขึ้นในปี 1959 สำหรับ Lisp
Steve314

1
@deadalnix - คุณรู้หรือไม่ว่าอย่างน้อยหนึ่ง Java VM ใช้ GC การนับการอ้างอิงที่สามารถ (เกือบ) สามารถดำเนินการโดยใช้ C ++ - สไตล์ RAII โดยใช้คลาสตัวชี้สมาร์ท - แม่นยำเพราะมันมีประสิทธิภาพมากขึ้นสำหรับรหัสมัลติเธรด ดู www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf เหตุผลหนึ่งที่คุณไม่เห็นสิ่งนี้ในทางปฏิบัติใน C ++ คือการรวบรวม GC ปกติ - มันสามารถรวบรวมรอบ แต่ไม่สามารถเลือกคำสั่ง destructor ที่ปลอดภัยในการปรากฏตัวของรอบและดังนั้นจึงไม่สามารถมั่นใจได้ว่าการล้าง destructor ที่เชื่อถือได้
Steve314

8

คุณถามว่าเพราะเหตุใดภาษาเหล่านี้จึงไม่ได้รับการอัปเดตเพื่อรวมตัวรวบรวมขยะที่ไม่จำเป็น

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


6

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

หรือระบบปฏิบัติการ คุณจะเริ่มต้นการรวบรวมขยะได้อย่างไรก่อนที่คุณจะเริ่มเคอร์เนล

C ถูกออกแบบมาสำหรับระดับต่ำใกล้กับงานฮาร์ดแวร์ ปัญหา? มันเป็นภาษาที่ดีที่เป็นตัวเลือกที่ดีสำหรับงานในระดับที่สูงขึ้นมากมายเช่นกัน czars ภาษาตระหนักถึงการใช้งานเหล่านี้ แต่พวกเขาต้องการที่จะสนับสนุนข้อกำหนดของไดรเวอร์อุปกรณ์รหัสฝังตัวและระบบปฏิบัติการเป็นสำคัญ


2
ดีสำหรับระดับสูงหรือไม่ ฉันดื่มเครื่องดื่มทั่วแป้นพิมพ์
DeadMG

5
เขาพูดว่า "งานในระดับที่สูงขึ้นมากมาย" เขาสามารถนับหมุนรอบได้ (หนึ่งสองสองมาก ... ) และเขาก็ไม่ได้พูดอะไรที่สูงไปกว่าสิ่งใด แม้ว่าจะเป็นเรื่องจริง - หลักฐานที่แสดงว่าโครงการระดับสูงที่สำคัญจำนวนมากได้รับการพัฒนาอย่างประสบความสำเร็จใน C. อาจมีทางเลือกที่ดีกว่าสำหรับโครงการเหล่านั้นจำนวนมาก แต่โครงการทำงานเป็นหลักฐานที่ดีกว่าการคาดเดาเกี่ยวกับสิ่งที่อาจ ได้รับ
Steve314

มีระบบปฏิบัติการที่จัดการบางระบบและทำงานได้ค่อนข้างดี อันที่จริงแล้วเมื่อคุณจัดการทั้งระบบประสิทธิภาพที่ได้รับจากการใช้รหัสที่ได้รับการจัดการจะลดลงต่ำกว่าจนถึงเร็วกว่าโค้ดที่ไม่ได้รับการจัดการในสถานการณ์จริง แน่นอนว่าทั้งหมดนี้คือ "research OS" - ไม่มีทางที่จะทำให้มันเข้ากันได้กับโค้ดที่ไม่มีการจัดการที่มีอยู่นอกเหนือจากการสร้าง OS ที่ไม่มีการจัดการเสมือนจริงทั้งหมดภายใน OS ที่มีการจัดการ Microsoft ได้แนะนำในบางจุดที่พวกเขาอาจแทนที่ Windows Server ด้วยหนึ่งในนั้นแม้ว่าจะมีการเขียนรหัสเซิร์ฟเวอร์มากขึ้นบน. NET
Luaan

6

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

คำถามอื่นคือทำไม C และ C ++ ไม่มีตัวรวบรวมขยะ ฉันรู้ว่า C ++ มีคู่อยู่รอบตัว แต่พวกเขาไม่ได้รับความนิยมจริงๆเพราะพวกเขาถูกบังคับให้ต้องจัดการกับภาษาที่ไม่ได้ออกแบบมาให้เป็น GC-ed ตั้งแต่แรกและผู้คนที่ยังคงใช้ C ++ ใน อายุนี้ไม่ได้เป็น GC จริงๆ

นอกจากนี้แทนที่จะเพิ่ม GC ลงในภาษาที่ไม่ใช่ GC-ed เก่าจริง ๆ แล้วมันง่ายกว่าที่จะสร้างภาษาใหม่ที่มีไวยากรณ์เหมือนกันเกือบทั้งหมดในขณะที่สนับสนุน GC Java และ C # เป็นตัวอย่างที่ดีของสิ่งนี้


1
อยู่ที่ไหนสักแห่งบน programmers.se หรือ SO มีบางคนอ้างว่ามีใครบางคนกำลังทำงานเกี่ยวกับสิ่งที่เก็บขยะด้วยตัวเอง - IIRC โดยพื้นฐานแล้วใช้ VM โดยใช้ภาษา GC โดยมีกลุ่มย่อย bootstrapping ใช้ในการสร้าง GC เอง ฉันลืมชื่อ เมื่อฉันมองเข้าไปมันกลับกลายเป็นว่าพวกเขาไม่เคยประสบความสำเร็จในการก้าวกระโดดจากเซตย่อยที่ไม่มี GC ไปจนถึงระดับ GC ที่ทำงาน นี่เป็นไปได้ในหลักการ แต่ AFAIK ไม่เคยประสบความสำเร็จในทางปฏิบัติ - แน่นอนว่าเป็นกรณีของการทำสิ่งต่าง ๆ อย่างหนัก
Steve314

@ Steve314: ฉันชอบที่จะเห็นว่าถ้าคุณเคยจำที่คุณพบมัน!
hugomg

พบมัน! ดูความคิดเห็นเพื่อstackoverflow.com/questions/3317329/…อ้างถึง Klein VM ส่วนหนึ่งของปัญหาที่พบ - คำถามถูกปิด
Steve314

BTW - ฉันดูเหมือนจะไม่สามารถเริ่มความคิดเห็นด้วย @missingno - อะไรที่ให้?
Steve314

@ steve314: เมื่อได้รับคำตอบที่แนบมากับกระทู้นี้ฉันได้รับการแจ้งเตือนสำหรับความคิดเห็นทั้งหมดแล้ว การทำ @ -post ในกรณีนี้จะซ้ำซ้อนและไม่ได้รับอนุญาตจาก SE (อย่าถามฉันว่าทำไม ) (สาเหตุที่แท้จริงว่าเป็นเพราะหมายเลขของฉันหายไป)
hugomg

5

มีปัญหาต่าง ๆ รวมถึง ...

  • แม้ว่า GC ถูกประดิษฐ์ขึ้นก่อน C ++ และอาจเป็นก่อน C ทั้ง C และ C ++ ถูกนำไปใช้ก่อนที่ GCs จะได้รับการยอมรับอย่างกว้างขวางว่าเป็นจริง
  • คุณไม่สามารถใช้ภาษาและแพลตฟอร์ม GC ได้อย่างง่ายดายหากไม่มีภาษาที่ไม่ใช่ GC พื้นฐาน
  • ถึงแม้ว่า GC จะมีประสิทธิภาพมากกว่า non-GC สำหรับรหัสแอพพลิเคชั่นทั่วไปที่พัฒนาขึ้นในไทม์สเกลทั่วไป ฯลฯ แต่ก็มีปัญหาที่ความพยายามในการพัฒนามากขึ้นคือการแลกเปลี่ยนที่ดีและการจัดการหน่วยความจำแบบพิเศษจะดีกว่า GC ทั่วไป นอกจากนี้โดยทั่วไปแล้ว C ++ นั้นมีประสิทธิภาพมากกว่าภาษา GC ส่วนใหญ่ถึงแม้จะไม่ได้มีการพัฒนาเพิ่มเติม
  • GC ไม่ปลอดภัยกว่า C ++ แบบ RAII ในระดับสากล RAII อนุญาตให้ทรัพยากรอื่นนอกเหนือจากหน่วยความจำถูกลบทิ้งโดยอัตโนมัติเนื่องจากสนับสนุนการทำลายที่เชื่อถือได้และทันเวลา สิ่งเหล่านี้ไม่สามารถใช้ร่วมกับวิธีการทั่วไปของ GC ได้เนื่องจากปัญหาเกี่ยวกับรอบการอ้างอิง
  • ภาษา GC มีลักษณะการรั่วไหลของหน่วยความจำชนิดของตัวเองโดยเฉพาะที่เกี่ยวข้องกับหน่วยความจำที่จะไม่ถูกใช้อีกครั้ง แต่เมื่อการอ้างอิงที่มีอยู่มีอยู่ซึ่งไม่เคยถูกลบล้างหรือเขียนทับ ความต้องการที่จะทำสิ่งนี้อย่างชัดเจนไม่แตกต่างกันในหลักการกว่าความต้องการdeleteหรือfreeอย่างชัดเจน วิธีการ GC ยังคงมีข้อดี - ไม่มีการอ้างอิงที่ห้อยต่องแต่ง - และการวิเคราะห์แบบคงที่สามารถตรวจจับได้ในบางกรณี แต่อีกครั้งไม่มีวิธีแก้ปัญหาที่สมบูรณ์แบบสำหรับทุกกรณี

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

C ++ ที่มีการจัดการของ Microsoft นั้นมีความสามารถอย่างน้อยที่สุดในการผสม GC และไม่ใช่ GC ในแอปพลิเคชันเดียวกันทำให้มีข้อดีและข้อได้เปรียบจากการผสมกัน แต่ฉันไม่มีประสบการณ์ที่จะพูดว่ามันทำงานได้ดีแค่ไหน

ลิงก์ซ้ำลิงก์ไปยังคำตอบที่เกี่ยวข้องของฉัน ...


4

การรวบรวมขยะไม่สามารถใช้งานร่วมกับภาษาระบบที่ใช้ในการพัฒนาไดรเวอร์สำหรับฮาร์ดแวร์ที่มีคุณสมบัติ DMA

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

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

ดังนั้นตอนนี้คุณต้องมีส่วนผสมของบัฟเฟอร์ DMA ที่เคลื่อนที่ไม่ได้และวัตถุที่จัดการโดย GC ซึ่งหมายความว่าคุณมีข้อเสียทั้งหมดของทั้งคู่


เนื้อหาข้อเสียทั้งหมดของทั้งคู่ แต่อินสแตนซ์ของข้อเสียแต่ละข้อน้อยกว่าและเหมือนกันสำหรับข้อดี เห็นได้ชัดว่ามีความซับซ้อนในการจัดการหน่วยความจำหลายประเภทที่จะจัดการ แต่อาจมีความซับซ้อนที่หลีกเลี่ยงได้โดยการเลือกม้าที่เหมาะสมสำหรับแต่ละหลักสูตรภายในรหัสของคุณ ไม่แน่นะฉันจินตนาการ แต่มีช่องว่างทางทฤษฎีที่นั่น ฉันได้คาดการณ์เกี่ยวกับการผสม GC และไม่ใช่ GC ในภาษาเดียวกันก่อนหน้านี้ แต่ไม่ใช่สำหรับไดรเวอร์อุปกรณ์ - มากขึ้นสำหรับการใช้งาน GC เป็นส่วนใหญ่ แต่มีไลบรารีโครงสร้างข้อมูลระดับต่ำที่จัดการด้วยตนเอง
Steve314

@ Steve314: คุณจะไม่พูดว่าการจำวัตถุใดที่จำเป็นต้องได้รับการปลดปล่อยด้วยตนเองนั้นเป็นเรื่องยากเหมือนการจดจำที่จะทำให้ทุกอย่างเป็นอิสระ? (แน่นอนว่าสมาร์ทพอยน์เตอร์สามารถช่วยเหลือได้เช่นกันดังนั้นจึงไม่มีปัญหาใหญ่) และคุณต้องการพูลที่แตกต่างกันสำหรับวัตถุที่จัดการด้วยตนเองเทียบกับวัตถุที่ถูกรวบรวม / อัดได้ มีความซับซ้อนมากขึ้นเป็นพิเศษ
Ben Voigt

2
ไม่ว่าจะมีการแบ่งที่ชัดเจนระหว่างรหัสระดับสูงซึ่งเป็น GC ทั้งหมดและรหัสระดับต่ำที่เลือกไม่ใช้ GC ฉันพัฒนาความคิดเป็นหลักในขณะที่ดู D เมื่อหลายปีก่อนซึ่งช่วยให้คุณสามารถเลือกไม่ใช้ GC แต่ไม่อนุญาตให้คุณเลือกที่จะกลับมาใช้ตัวอย่างเช่นไลบรารีต้นไม้ B + คอนเทนเนอร์โดยรวมควรเป็น GC แต่โหนดโครงสร้างข้อมูลอาจไม่ใช่ - มีประสิทธิภาพมากกว่าในการสแกนแบบกำหนดเองผ่านทางโหนดใบไม้เท่านั้นเพื่อให้ GC ทำการค้นหาแบบเรียกซ้ำผ่านโหนดสาขา อย่างไรก็ตามการสแกนนั้นไม่จำเป็นต้องรายงานรายการที่มีอยู่ไปยัง GC
Steve314

ประเด็นก็คือมันเป็นฟังก์ชั่นที่มีอยู่ การรักษาโหนดต้นไม้ B + เป็นการจัดการหน่วยความจำ WRT พิเศษไม่แตกต่างจากการจัดการกับโหนดWRT แบบพิเศษซึ่งเป็นโหนดต้นไม้ B + มันเป็นไลบรารีที่ถูกห่อหุ้มและรหัสแอปพลิเคชันไม่จำเป็นต้องรู้ว่าพฤติกรรมของ GC ถูกข้าม / ใส่กล่องพิเศษ นอกจากนั้นอย่างน้อยในเวลานั้นมันเป็นไปไม่ได้ใน D - อย่างที่ฉันบอกไม่มีทางเลือกและรายงานรายการที่มีให้ GC เป็นราก GC ที่เป็นไปได้
Steve314

3

เนื่องจาก C & C ++ เป็นภาษาระดับค่อนข้างต่ำที่มีไว้สำหรับวัตถุประสงค์ทั่วไปเช่นเพื่อใช้กับโปรเซสเซอร์ 16 บิตที่มีหน่วยความจำ 1MB ในระบบฝังตัวซึ่งไม่สามารถเสียหน่วยความจำด้วย gc


1
"ระบบฝังตัว"? ในขณะที่ C เป็นมาตรฐาน (1989) มันจำเป็นต้องสามารถจัดการพีซีที่มีหน่วยความจำ 1 MB
dan04

ฉันเห็นด้วยฉันอ้างถึงตัวอย่างที่เป็นปัจจุบันมากขึ้น
Petruza

1MB ??? ศักดิ์สิทธิ์ schmoley ใครจะต้องการ RAM ที่มาก? </billGates>
ทำเครื่องหมาย K Cowan

2

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

สำหรับความรู้ของฉันคุณไม่สามารถเขียน Java โดยไม่มีตัวรวบรวมขยะ ค้นหาเล็ก ๆ น้อย ๆ เปิดขึ้นนี้

ความแตกต่างที่สำคัญระหว่าง Java และ C / C ++ คือใน C / C ++ ตัวเลือกจะเป็นของคุณเสมอในขณะที่ใน Java คุณมักจะไม่มีตัวเลือกโดยการออกแบบ


และยังมีการสะสมขยะโดยเฉพาะให้ดีขึ้นมีประสิทธิภาพมากขึ้นและเหมาะสมกับภาษามากขึ้น :)
สูงสุด

ไม่คุณไม่สามารถใช้ RTTI เพื่อค้นหากราฟวัตถุแบบไดนามิกใน C / C ++: มันเป็นวัตถุข้อมูลแบบเก่าที่ทำลายทุกอย่าง ไม่มีข้อมูล RTTI เพียงอย่างเดียวที่เก็บไว้ในวัตถุข้อมูลเก่าแบบธรรมดาที่จะอนุญาตให้ตัวรวบรวมขยะแยกความแตกต่างระหว่างพอยน์เตอร์และไม่ใช่พอยน์เตอร์ภายในวัตถุนั้น ยิ่งไปกว่านั้นพอยน์เตอร์ไม่จำเป็นต้องจัดตำแหน่งอย่างสมบูรณ์บนฮาร์ดแวร์ทั้งหมดดังนั้นเมื่อมีวัตถุ 16 ไบต์มี 9 ตำแหน่งที่เป็นไปได้ที่ตัวชี้ 64 บิตสามารถเก็บไว้ได้เพียงสองแห่งเท่านั้นที่ไม่ทับซ้อนกัน
cmaster

2

เป็นการแลกเปลี่ยนระหว่างประสิทธิภาพและความปลอดภัย

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

แน่นอนว่าข้อดีคือสามารถสร้างภาษาโดยไม่มีพอยน์เตอร์หรือไม่มีการรั่วไหลของหน่วยความจำดังนั้นจึงมีแนวโน้มที่จะสร้างรหัสที่ถูกต้อง

อาจมี 'ศาสนา' เล็กน้อยในการอภิปรายเหล่านี้บางครั้ง - ถูกเตือน!


1

นี่คือรายการปัญหาโดยธรรมชาติของ GC ซึ่งทำให้ไม่สามารถใช้งานได้ในภาษาระบบเช่น C:

  • GC ต้องทำงานต่ำกว่าระดับรหัสที่วัตถุจัดการอยู่ ไม่มีระดับดังกล่าวในเคอร์เนล

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

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

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

    สิ่งนี้ต้องการข้อมูลประเภทนั้นอย่างแน่นอนจะถูกเก็บไว้ในทุก ๆ วัตถุ อย่างไรก็ตามทั้ง C และ C ++ อนุญาตให้วัตถุข้อมูลเก่าธรรมดาที่ไม่มีข้อมูลประเภท

  • GC เป็นธุรกิจที่ช้ามาก โปรแกรมเมอร์ที่เข้าสังคมกับ Java อาจไม่เข้าใจสิ่งนี้ แต่โปรแกรมสามารถเรียงลำดับได้เร็วขึ้นเมื่อไม่ได้ใช้งานใน Java และหนึ่งในปัจจัยที่ทำให้ Java ช้าลงคือ GC นี่คือสิ่งที่ห้ามไม่ให้มีการใช้ภาษา GCed เช่น Java ในการประมวลผลขั้นสูง หากเครื่องของคุณมีค่าใช้จ่ายต่อการใช้พลังงานเป็นล้านปีคุณไม่ต้องการจ่ายแม้แต่ 10% สำหรับการเก็บขยะ

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

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