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


67

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

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

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

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

แก้ไข: คำถามที่แนะนำว่าซ้ำซ้อนเป็นคำถามเฉพาะของตระกูล Unix ของระบบปฏิบัติการ คำตอบอันดับแรกของมันยังระบุเครื่องมือเฉพาะสำหรับ Linux (เช่น Valgrind) คำถามนี้มีขึ้นเพื่อครอบคลุมระบบปฏิบัติการที่ "ไม่ธรรมดา" ส่วนใหญ่และทำไมจึงเป็นหรือไม่ใช่แนวปฏิบัติที่ดีในการเพิ่มหน่วยความจำที่จำเป็นตลอดอายุการใช้งานของโปรแกรม



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

3
และแน่นอนว่าคุณสามารถเขียน C ++ ได้โดยไม่ต้องลบไฟล์ใด ๆ เลยและมันก็จะดีสำหรับหน่วยความจำ
Nikko

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

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

คำตอบ:


108

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

มันไม่ได้บังคับ แต่อาจมีประโยชน์ (รวมถึงข้อเสียบางอย่าง)

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

อย่างไรก็ตามโดยการปล่อยหน่วยความจำทั้งหมดเมื่อสิ้นสุดการดำเนินการอย่างชัดเจน

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

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

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


12
จุดดีเกี่ยวกับการพัฒนานิสัยการเขียนโปรแกรมที่ดี
Lawrence

4
โดยทั่วไปฉันเห็นด้วยอย่างยิ่งกับคำแนะนำนี้ การรักษานิสัยที่ดีด้วยความทรงจำเป็นสิ่งสำคัญมาก อย่างไรก็ตามฉันคิดว่ามีข้อยกเว้น ตัวอย่างเช่นหากสิ่งที่คุณจัดสรรเป็นกราฟบ้า ๆ ที่จะใช้เวลาหลายวินาทีในการสำรวจและฟรี "ถูกต้อง" คุณจะต้องปรับปรุงประสบการณ์ผู้ใช้โดยเพียงแค่ปิดโปรแกรมและปล่อยให้ระบบปฏิบัติการ nuke
GrandOpener

1
มันปลอดภัยสำหรับทุกระบบปฏิบัติการ "ปกติ" (ไม่ฝังตัวพร้อมการป้องกันหน่วยความจำ) ที่ทันสมัยและจะเป็นข้อผิดพลาดร้ายแรงหากไม่ใช่ หากกระบวนการที่ไม่มีสิทธิพิเศษอาจสูญเสียหน่วยความจำอย่างถาวรซึ่งระบบปฏิบัติการจะไม่เรียกคืนจากนั้นการเรียกใช้หลายครั้งอาจทำให้ระบบหน่วยความจำไม่เพียงพอ สุขภาพในระยะยาวของระบบปฏิบัติการไม่สามารถขึ้นอยู่กับการขาดข้อบกพร่องในโปรแกรมที่ไม่มีสิทธิพิเศษ (แน่นอนว่านี่เป็นการเพิกเฉยต่อสิ่งต่างๆเช่นเซ็กเมนต์หน่วยความจำที่ใช้ร่วมกันของ Unix ซึ่งได้รับการสนับสนุนจาก swap space ที่ดีที่สุดเท่านั้น)
Peter Cordes

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

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

11

การเพิ่มหน่วยความจำเมื่อสิ้นสุดการทำงานของโปรแกรมเป็นเพียงการเสียเวลาของ CPU มันเหมือนกับการจัดระเบียบบ้านก่อนที่จะออกจากวงโคจร

อย่างไรก็ตามบางครั้งสิ่งที่โปรแกรมการทำงานระยะสั้นสามารถเปลี่ยนเป็นส่วนหนึ่งของโปรแกรมที่ทำงานได้นานกว่ามาก จากนั้นการปล่อยสิ่งของก็เป็นสิ่งจำเป็น หากนี่ไม่ได้คิดอย่างน้อยก็อาจเกี่ยวข้องกับการทำงานซ้ำอย่างมาก

วิธีแก้ปัญหาที่ฉลาดวิธีหนึ่งคือ "talloc" ซึ่งช่วยให้คุณทำการจัดสรรหน่วยความจำจำนวนมากแล้วโยนมันทิ้งด้วยการโทรเพียงครั้งเดียว


1
สมมติว่าคุณรู้ว่าระบบปฏิบัติการของคุณไม่มีการรั่วไหลของตัวเอง
WGroleau

5
"เสียเวลาของ CPU" แม้ว่าจะใช้เวลาน้อยมากก็ตาม มักจะเร็วกว่าfree malloc
Paul Draper

@ PaulDraper Aye การเสียเวลาในการแลกเปลี่ยนทุกอย่างกลับมีความสำคัญมากกว่า
Deduplicator

5

คุณสามารถใช้ภาษาที่มีการรวบรวมขยะ (เช่น Scheme, Ocaml, Haskell, Common LISP และแม้แต่ Java, Scala, Clojure)

(ในภาษา GC-ed ส่วนใหญ่ไม่มีหนทางที่จะจำได้อย่างอิสระและด้วยตนเอง ! บางครั้งค่าบางอย่างอาจสรุปได้เช่น GC และระบบรันไทม์จะปิดค่าจัดการไฟล์เมื่อค่านั้นไม่สามารถเข้าถึงได้ แต่นี่ไม่ใช่ แน่นอนว่าไม่น่าเชื่อถือและคุณควรปิดการจัดการไฟล์ของคุณแทนอย่างชัดเจน

คุณอาจจะยังสำหรับโปรแกรมของคุณเขียนใน C (หรือแม้กระทั่ง C ++) ใช้เก็บขยะ Boehm ของอนุรักษ์นิยม จากนั้นคุณจะแทนที่ทั้งหมดmallocด้วยGC_malloc และไม่ต้องกังวลกับการfreeใช้ตัวชี้ใด ๆ แน่นอนคุณต้องเข้าใจข้อดีข้อเสียของการใช้ GC ของ Boehm อ่านยังคู่มือ GC

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

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

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

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

ขอให้สังเกตว่าระบบfreeมักจะไม่ปล่อยหน่วยความจำระบบปฏิบัติการ (เช่นโดยการเรียกmunmap (2)ในระบบ POSIX) mallocแต่มักจะทำเครื่องหมายโซนหน่วยความจำเป็นนำมาใช้ใหม่ในอนาคตโดย โดยเฉพาะอย่างยิ่งพื้นที่ที่อยู่เสมือน (เช่นเห็นผ่าน/proc/self/mapsบน Linux ดูproc (5) .... ) อาจไม่หดตัวหลังจากfree(ดังนั้นยูทิลิตี้เช่นpsหรือtopกำลังรายงานจำนวนหน่วยความจำที่ใช้สำหรับกระบวนการของคุณ)


3
"บางครั้งค่าบางอย่างอาจสรุปได้เช่น GC และระบบรันไทม์จะปิดค่าหมายเลขอ้างอิงไฟล์เมื่อค่านั้นไม่สามารถเข้าถึงได้" คุณอาจต้องการเน้นว่าในภาษา GCed ส่วนใหญ่ไม่มีการรับประกันว่าหน่วยความจำใด ๆ จะถูกเรียกคืนหรือ Finalizer ใด ๆ ที่เคยทำงานแม้จะอยู่ที่ exit: stackoverflow.com/questions/7880569/…
Deduplicator

ฉันชอบคำตอบนี้เป็นการส่วนตัวเพราะมันกระตุ้นให้เราใช้ GC (เช่นวิธีการอัตโนมัติมากขึ้น)
Ta Thanh Dinh

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

3

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

หนึ่งในกรณีที่ทรงพลังที่สุดที่ฉันพบ (มากไปกว่านั้น) คือมีคนเขียนโค้ดจำลองขนาดเล็กที่ทำงานในปฏิบัติการของพวกเขา พวกเขาบอกว่า "เราต้องการให้รหัสนี้รวมเข้ากับการจำลอง" ฉันถามพวกเขาว่าพวกเขาวางแผนที่จะเริ่มต้นใหม่ระหว่างการทำงานของ monte-carlo ได้อย่างไรและพวกเขามองมาที่ฉันอย่างว่างเปล่า "คุณหมายถึงการเริ่มต้นใหม่อย่างไรคุณเพียงเรียกใช้โปรแกรมด้วยการตั้งค่าใหม่"

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

สำหรับตัวอย่างของสิ่งที่จะได้รับสิ่งแปลก ๆ ดูที่ภาษาที่มีการจัดการจัดการกับการสรุปในตอนท้ายของกระบวนการหรือวิธีการที่ C # เกี่ยวข้องกับการหยุดเขียนโปรแกรมของ Application Domains พวกเขาผูกตัวเองเป็นปมเพราะมีสมมติฐานที่ตกลงมาในรอยแตกในกรณีที่รุนแรงเหล่านี้


1

ไม่สนใจภาษาที่คุณไม่ได้เพิ่มหน่วยความจำด้วยตนเอง ...

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


2
ดูเหมือนว่าจะทำซ้ำจุดที่ทำ (และอธิบายได้ดีกว่า) ในคำตอบยอดนิยมที่โพสต์เมื่อไม่กี่ชั่วโมงก่อน: "มันอาจจะง่ายกว่ามากในการย้ายรหัสที่ใช้หน่วยความจำร่วมกับการจัดสรรและการจัดสรรคืน ในบริบทที่แตกต่างกันซึ่งจำเป็นต้องมีการควบคุมเวลาการใช้งานสำหรับหน่วยความจำโดยผู้ใช้ของคอมโพเนนต์ ... "
gnat

1

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

ทำสิ่งต่าง ๆ ในขณะที่ความเข้าใจของคุณเกี่ยวกับพวกเขายังคงสด

เป็นการลงทุนขนาดเล็กที่อาจให้ผลตอบแทนสูงในอนาคต


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

1
@gnat ในรูปแบบที่ซับซ้อนและไม่ชัดเจน - ใช่ ในแถลงการณ์ที่ชัดเจน - ไม่ ให้ความสำคัญกับคุณภาพของการตอบไม่ใช่ความเร็ว
Agent_L

1
ฉลาดคุณภาพคำตอบยอดนิยมดูเหมือนจะดีกว่ามากในการอธิบายประเด็นนี้
gnat

1

ไม่ไม่จำเป็น แต่เป็นความคิดที่ดี

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

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

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

อย่างไรก็ตามมีอย่างน้อยหนึ่งกรณีที่ดีกว่าที่จะไม่เพิ่มหน่วยความจำก่อนสิ้นสุดโปรแกรม

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

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

สิ่งสำคัญคือให้สังเกตว่าในภาษา OO การเรียก destructor ของวัตถุจะบังคับให้หน่วยความจำถูกสลับ หากคุณต้องทำเช่นนี้คุณอาจเพิ่มหน่วยความจำ


1
คุณสามารถอ้างถึงบางสิ่งบางอย่างเพื่อสนับสนุนแนวคิดที่ว่าหน่วยความจำเพจเอาต์จำเป็นต้องได้รับการเพจเพื่อยกเลิกการจัดสรร? เห็นได้ชัดว่าไม่มีประสิทธิภาพแน่นอนว่าระบบปฏิบัติการสมัยใหม่นั้นฉลาดกว่านั้น!

1
@ จอนแห่งการค้าขายทั้งหมดระบบปฏิบัติการที่ทันสมัยเป็นภาษาที่ฉลาด แต่ภาษาที่ทันสมัยที่สุดไม่ใช่ภาษา เมื่อคุณว่าง (บางอย่าง) คอมไพเลอร์จะวาง "บางอย่าง" ลงในสแต็กจากนั้นโทรฟรี () การวางลงบนสแต็กต้องเปลี่ยนเป็นแรมถ้ามันสลับออก
Jeffiekins

@JonofAllTrades รายชื่อฟรีจะมีผลกระทบนั้นนั่นคือการใช้งาน malloc ที่ล้าสมัยไปแล้ว แต่ระบบปฏิบัติการไม่สามารถป้องกันคุณจากการใช้งานดังกล่าวได้

0

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

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

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

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