หน่วยความจำรั่วไหลตกลงไหม [ปิด]


231

เป็นที่ยอมรับหรือไม่ว่ามีหน่วยความจำรั่วในแอพพลิเคชั่น C หรือ C ++ ของคุณ?

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

ถ้าห้องสมุดบุคคลที่สามบังคับให้คุณทำเช่นนี้ล่ะ จะปฏิเสธที่จะใช้ห้องสมุดบุคคลที่สามไม่ว่ามันจะดีแค่ไหน

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


50
หากการใช้หน่วยความจำไม่เพิ่มขึ้นตามกาลเวลามันก็จะไม่รั่ว
mpez0

4
แอปพลิเคชั่นส่วนใหญ่ (รวมถึงโปรแกรม. NET ทั้งหมด) มีบัฟเฟอร์อย่างน้อยสองสามตัวที่จัดสรรเพียงครั้งเดียวและไม่เคยเป็นอิสระอย่างชัดเจนดังนั้นคำจำกัดความของ mpez0 จึงมีประโยชน์มากกว่า
Ben Voigt

2
ใช่ถ้าคุณมีความจำไม่ จำกัด
ผู้ใช้

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

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

คำตอบ:


329

เลขที่

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

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

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

คล้ายกับคำเตือนของคอมไพเลอร์ - คำเตือนจะเป็นอันตรายต่อแอปพลิเคชันของฉันหรือไม่ อาจจะไม่.

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

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

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

-

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


57
จริงและไม่จริงในเวลาเดียวกัน ที่สุดของเราส่วนใหญ่เป็นค่าจ้างทาสและความปรารถนาใด ๆ สำหรับงานฝีมือต้องใช้เบาะหลังกับความต้องการของธุรกิจ หากห้องสมุดของบุคคลที่สามมีการรั่วไหลและประหยัดเวลาในการทำงาน 2 สัปดาห์อาจจะมีกรณีศึกษาทางธุรกิจที่จะใช้งาน ฯลฯ
Cervo

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

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

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

5
อืมคือ "ไม่รั่วหน่วยความจำ" "สมบูรณ์แบบ"?
JohnMcG

80

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


12
ในทางเทคนิคแล้วการรั่วไหลคือหน่วยความจำที่ถูกจัดสรรและการอ้างอิงทั้งหมดจะหายไป การไม่จัดสรรคืนหน่วยความจำในตอนท้ายเป็นเพียงการขี้เกียจ
Martin York

17
หากคุณมีการรั่วไหลของหน่วยความจำ 1 ครั้ง 4 GB นั่นเป็นปัญหา
John Dibling

21
ไม่สำคัญว่ามันจะเติบโตหรือไม่ โปรแกรมอื่นไม่สามารถใช้หน่วยความจำได้หากคุณมีการจัดสรร
Bill the Lizard

8
> โปรแกรมอื่นไม่สามารถใช้หน่วยความจำได้หากคุณมีการจัดสรร ระบบปฏิบัติการสามารถสลับหน่วยความจำของคุณไปยังดิสก์ได้ตลอดเวลาและอนุญาตให้แอปพลิเคชันอื่นใช้ RAM ที่คุณไม่ได้ใช้ประโยชน์
Max Lybbert

4
หากโปรแกรมมีอายุสั้นมากการรั่วไหลอาจไม่เลวร้ายนัก นอกจากนี้ในขณะที่ไม่เหมาะเพจจิ้งก็ไม่แพงเท่าที่นี่ทำให้มันเป็นเพราะโปรแกรมไม่ได้สนใจในหน่วยความจำนั้น (และจะไม่สลับตลอดเวลา) - เว้นแต่แน่นอนคุณมี GC ...
Arafangion

79

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

#define BLK ((size_t)1024)
while(1){
    void * vp = malloc(BLK);
}

โปรดทราบว่าทุกครั้งรอบลูป while (1), 1024 (+ ค่าใช้จ่าย) จะถูกจัดสรรไบต์และที่อยู่ใหม่ที่กำหนดให้กับ vp; ไม่มีตัวชี้ที่เหลือไปยังบล็อก malloc'ed ก่อนหน้า โปรแกรมนี้รับประกันว่าจะทำงานจนกว่าฮีพจะหมดและไม่มีวิธีกู้หน่วยความจำ malloc'ed ใด ๆ หน่วยความจำคือ "รั่ว" ออกจากกองไม่เคยเห็นอีกเลย

แม้ว่าสิ่งที่คุณกำลังอธิบายดูเหมือนว่า

int main(){
    void * vp = malloc(LOTS);
    // Go do something useful
    return 0;
}

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

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


พิจารณาการจัดสรรนี้สองสามโหล ตอนนี้ให้พิจารณาว่าต้องย้ายร่างกาย "หลัก" ไปยังรูทีนที่เรียกหลาย ๆ ครั้ง สนุก. - ฉันเห็นด้วยกับความรู้สึกว่ามันไม่ใช่ปัญหาใหญ่ในสถานการณ์นี้ แต่สถานการณ์เปลี่ยนไป อย่างที่พวกเขาพูดให้เขียนรหัสเสมอราวกับว่าคนที่รักษามันรู้ว่าคุณอยู่ที่ไหน
peterchen

2
ประเด็นก็คือหน่วยความจำที่มี malloc'ed และเก็บไว้จนกว่าโปรแกรมจะเรียก _exit () ไม่ใช่ "leaked"
ชาร์ลีมาร์ติน

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

10
Mike นั่นไม่ใช่เรื่องจริง ในสภาพแวดล้อมที่สอดคล้องกับ C การสิ้นสุด main ทำให้ทรัพยากรกระบวนการทั้งหมดเป็นอิสระ ในสภาพแวดล้อมแบบฝังตัวเช่นที่คุณอธิบายคุณอาจเห็นสถานการณ์นั้น แต่คุณไม่มีหลัก ตอนนี้ฉันจะอนุญาตให้มีสภาพแวดล้อมที่ฝังตัวที่มีข้อบกพร่องซึ่งสิ่งนี้จะไม่เป็นจริง แต่จากนั้นฉันก็เห็นสภาพแวดล้อมที่มีข้อบกพร่องที่ไม่สามารถจัดการกับ + = ได้อย่างถูกต้องเช่นกัน
Charlie Martin

3
ใช่ตอนนี้คุณค้นพบแล้วว่าถ้าคุณmallocจำมากเกินไปมันเป็นเรื่องแย่ ก็ยังคงไม่รั่วไหล มันจะไม่รั่วไหลจนกว่าจะมีmallocหน่วยความจำที่อ้างอิงหายไป
Charlie Martin

39

ในทางทฤษฎีไม่มีในทางปฏิบัติมันขึ้นอยู่กับ

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

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

ในทางกลับกันถ้าฉันมีโปรแกรมที่ประมวลผลหลายล้านระเบียนและทำงานเป็นเวลานานหน่วยความจำรั่วขนาดเล็กอาจทำให้เครื่องทำงานช้าลง

สำหรับห้องสมุดของบุคคลที่สามที่มีรอยรั่วหากเกิดปัญหาขึ้นให้แก้ไขไลบรารีหรือค้นหาทางเลือกที่ดีกว่า หากไม่ก่อให้เกิดปัญหาจริงหรือไม่


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

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

"ถ้ามันไม่ได้ทำให้เกิดปัญหามันสำคัญจริงๆเหรอ?" ไม่มันไม่สำคัญเลย ฉันหวังว่าผู้คนจำนวนมากจะได้รับสิ่งนั้นแทนที่จะได้รับศาสนา
Imbue

2
@ จอห์น: นั่นเป็นคำถามของนักพัฒนาที่ขี้เกียจน้อยกว่าและคำถามเกี่ยวกับการพัฒนาซอฟต์แวร์ เราทุกคนทำผิดพลาดข้อผิดพลาดคือการค้าของเรา; เราทำให้พวกเขาแก้ไขได้นั่นคือสิ่งที่เราทำ มันมักจะมีความสมดุลระหว่างค่าใช้จ่ายล่วงหน้าและการบำรุงรักษาในระยะยาวความสมดุลนั้นไม่เคยตรงไปตรงมา
vfilby

1
จอห์นฉัน 100% เห็นด้วยกับคุณ .. Imbum คำถามคือ "คุณยอมรับได้เท่าไหร่" Sloppy เลอะเทอะ .. แล้วฉันจะทิ้งกุ้งไว้ที่หน้าจอของคุณ กลิ่นเหม็นคือกลิ่นเหม็น ทุกครั้งที่ถ้ำเราอุตสาหกรรมถ้ำของเรา หากคุณรู้ว่ามีการรั่วไหลและคุณรู้ว่าคุณเกิดขึ้นคุณควรแก้ไข
baash05

37

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

สิ่งนี้ไม่เป็นความจริง ระบบปฏิบัติการทั่วไปจัดการหน่วยความจำในหน้า 4KiB mallocและการจัดการหน่วยความจำประเภทอื่น ๆ จะได้รับเพจจากระบบปฏิบัติการและจัดการย่อยตามที่เห็นสมควร มีโอกาสมากที่free()จะไม่ส่งคืนหน้าเว็บไปยังระบบปฏิบัติการภายใต้สมมติฐานว่าโปรแกรมของคุณจะทำให้หน่วยความจำเพิ่มขึ้นในภายหลัง

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

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

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

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

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

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

สมมติว่าคุณจัดสรรบล็อกขนาด 100,000 ไบต์ (เพื่อความง่ายฉันจะเพิกเฉยต่อหน่วยความจำเพิ่มเติมที่จะต้องใช้ในการจัดการการจัดสรรเหล่านี้) สิ่งนี้ใช้ 1MB หรือ 250 หน้า ถ้าคุณสุ่ม 9000 บล็อกเหล่านี้โดยสุ่มคุณจะเหลือเพียง 1,000 บล็อก - แต่บล็อกเหล่านั้นกระจัดกระจายไปทั่ว ในทางสถิติประมาณ 5 หน้าจะว่างเปล่า อีก 245 คนจะมีบล็อกที่จัดสรรอย่างน้อยหนึ่งบล็อก จำนวนนั้นมีหน่วยความจำ 980KB ซึ่งไม่สามารถเรียกคืนได้จากระบบปฏิบัติการแม้ว่าตอนนี้คุณจะได้รับการจัดสรร 100KB เท่านั้น!

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

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


1
เกิดอะไรขึ้นถ้าโปรแกรมอื่น ๆ ต้องใช้หน่วยความจำที่โปรแกรมของคุณจะถือขึ้นโดยไม่จำเป็นดังนั้นแม้ว่าคุณอาจไม่จำเป็นต้อง mallocs ใด ๆ เพิ่มเติมฟรี () พื้นที่หน่วยความจำที่ไม่ได้ใช้ :)
MN

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

27

ไม่มีอะไรผิดปกติทางแนวคิดเกี่ยวกับการล้าง OS หลังจากแอปพลิเคชันทำงาน

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

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


เกี่ยวกับภาษาสคริปต์: Python ใช้การนับซ้ำ แต่มี GC เพียงเพื่อเพิ่มการอ้างอิงตามวัฏจักร ในภาษาอื่น ๆ โปรแกรมเมอร์มักจะหลีกเลี่ยงการอ้างอิงวัฏจักรอย่างชัดเจนโดยสิ้นเชิงซึ่งสร้างปัญหาอื่น ๆ
Blaisorblade

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

19

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

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

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

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

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

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

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

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

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

การเขียนโปรแกรมสมาร์ทมีความยืดหยุ่นและทั่วไป การเขียนโปรแกรมไม่ดีจะคลุมเครือ


ฉันชอบความคิดที่เป็นนิสัย ฉันก็เห็นด้วย ถ้าฉันเห็นหน่วยความจำรั่วฉันมักจะสงสัยว่า coder ตัดมุมไหน โดยเฉพาะอย่างยิ่งถ้ามันชัดเจน
baash05

นี่คือคำตอบที่ดีที่สุด ฉันได้เขียนโปรแกรมใน C ++ เป็นเวลา 5 ปีแล้วและฉันไม่เคยเขียนหน่วยความจำรั่วครั้งเดียว สาเหตุคือฉันไม่ได้เขียนรหัสที่มีแนวโน้มที่จะรั่วไหลหน่วยความจำ การออกแบบ C ++ ที่ดีนั้นคุณไม่ค่อยได้ใช้งานnewดังนั้นจึงช่วยลดการรั่วไหลของหน่วยความจำส่วนใหญ่ได้ทันที เฉพาะในกรณีที่คุณต้องใช้newจริงๆ ผลลัพธ์ของสิ่งนั้นnewจะต้องถูกวางไว้ในตัวชี้สมาร์ททันที หากคุณปฏิบัติตามกฎทั้งสองนี้คุณจะไม่มีทางรั่วความจำ (ยกเว้นบั๊กในไลบรารี) กรณีเดียวที่เหลืออยู่คือรอบซึ่งในกรณีที่คุณต้องรู้กับการใช้งานshared_ptr weak_ptr
David Stone

15

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

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

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

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


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

15

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

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

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

นี่ไม่ใช่แค่ทางทฤษฎี เมื่อใดก็ตามที่ฉันพบว่าตัวเองโหลดแอพมากเกินไปและดิสก์เริ่มสั่นฉันไม่คิดแม้แต่จะคลิก "ออก" ฉันไปที่เทอร์มินัลให้เร็วที่สุดและพิมพ์ killall -9 ... เพราะฉันรู้ว่า "ทางออก" จะทำให้แย่ลง


5
รักคำพูดนี้จาก Raymond Chen: "อาคารกำลังพังยับเยินอย่ารำคาญกวาดพื้นและล้างถังขยะและลบกระดานไวท์บอร์ดและไม่ต้องเข้าแถวที่ทางออกเพื่อให้ทุกคนสามารถย้ายเข้า / แม่เหล็กออกไปสิ่งที่คุณกำลังทำอยู่คือการทำให้ทีมรื้อถอนรอให้คุณทำงานทำความสะอาดที่ไม่มีจุดหมายเหล่านี้ให้เสร็จ " ( blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 )
Andreas Magnusson

11

ฉันแน่ใจว่ามีบางคนอาจคิดว่าใช่ แต่ก็ไม่ใช่ฉัน แทนที่จะบอกว่าไม่ฉันจะบอกว่านี่ไม่ใช่คำถามใช่ / ไม่ใช่ มีวิธีในการจัดการหรือมีหน่วยความจำรั่วและหลายระบบมี

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


นั่นเป็นตัวอย่างของอายุซอฟต์แวร์ วิชาที่น่าสนใจของการศึกษา
Konrad Rudolph

รีบูตอัตโนมัติทุกครั้งใช่มั้ย นาซ่าใช่มั้ย (* ดูที่ซีดีการติดตั้ง Microsoft Windows เก่า *) นี่จะอธิบายได้มาก ...
Christian Severin

8

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


ไม่จริงเพราะถ้ามันไม่ได้ใช้มันก็จะได้รับการเพจออก เมื่อแอพออกหน่วยความจำทั้งหมดจะถูกปล่อยออกมา
Eclipse

ตราบใดที่มีการจัดสรรโปรแกรมอื่น ๆ จะไม่สามารถใช้งานได้ มันจะไม่ได้รับการเพจออกถ้าคุณไม่จัดสรรคืน
Bill the Lizard

แน่นอนมัน - นั่นคือสิ่งที่หน่วยความจำเสมือนเป็นเรื่องเกี่ยวกับ คุณสามารถมี RAM จริง 1 GB และยังมี 4 กระบวนการแต่ละกระบวนการจัดสรรหน่วยความจำเสมือนอย่างเต็มที่ 2 GB (ตราบเท่าที่ไฟล์หน้าของคุณใหญ่พอ)
Eclipse

แน่นอนคุณจะได้รับปัญหาการเพจที่น่ารังเกียจหากกระบวนการเหล่านั้นใช้หน่วยความจำทั้งหมดนั้นอย่างแข็งขัน
Eclipse

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

8

ฉันสามารถนับจำนวนการรั่วไหล "ใจดี" ที่ฉันเห็นเมื่อเวลาผ่านไปได้

ดังนั้นคำตอบคือใช่มีคุณสมบัติมาก

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

ฉันได้เห็นวิธีการนี้ใช้เพื่อประโยชน์ที่ดีเยี่ยมสำหรับสิ่งต่าง ๆ ที่มีการนับที่ชัดเจนมากเช่นการทำงานของซีพียูต่อการขโมยและในระดับที่น้อยกว่ามากในบัฟเฟอร์ที่ใช้เพื่อเก็บ/proc/self/mapsสถานะซิงเกิลในตัวเก็บขยะแบบอนุรักษ์ของ Hans Boehm สำหรับ C / C ++ ซึ่งใช้ในการตรวจจับชุดของรูท ฯลฯ

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


1
คุณสามารถใช้ตัวชี้อันตรายเพื่อป้องกันการรั่วไหล
Demi

8

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

ในความเป็นจริงไม่จำเป็นต้องโทรฟรี () หรือลบทันทีก่อนที่คุณจะออก เมื่อกระบวนการออกจากหน่วยความจำทั้งหมดจะถูกเรียกคืนโดยระบบปฏิบัติการ (นี่เป็นกรณีที่มี POSIX ในระบบปฏิบัติการอื่น ๆ - โดยเฉพาะอย่างยิ่งที่ฝังตัว - YMMV)

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


ฉันขอแตกต่าง นั่นคือ “ หน่วยความจำรั่วต่อเนื่อง”
Konrad Rudolph

มันไม่รั่วไหลจนกว่าคุณจะ "สูญเสีย" การอ้างอิงไปยังวัตถุ สมมุติว่าถ้าใช้หน่วยความจำตลอดอายุการใช้งานของโปรแกรมแสดงว่าไม่มีการรั่วไหล หากการอ้างอิงไม่สูญหายจนกว่าจะเรียก exit () จะไม่มีการรั่วไหลอย่างแน่นอน
nsayer

Amiga DOS เป็น O / SI ล่าสุดที่มองว่าไม่ได้ทำความสะอาดหลังกระบวนการ อย่างไรก็ตามโปรดทราบว่าหน่วยความจำที่ใช้ร่วมกันของ System V IPC สามารถถูกทิ้งไว้แม้ว่าจะไม่มีกระบวนการใดใช้
Jonathan Leffler

ปาล์มไม่ได้เพิ่มหน่วยความจำ "รั่ว" จนกว่าคุณจะ hotsync มันมาได้ดีหลังจากที่เอมิ ฉันใช้งานแอพพลิเคชั่นตัวเลียนแบบมือถือที่มีรอยรั่ว .. พวกเขาไม่เคยไปที่ฝ่ามือของฉัน
baash05

6

นี่เป็นโดเมนเฉพาะดังนั้นจึงไม่ค่อยคุ้มค่าในการตอบ ใช้หัวของคุณเลว

  • ระบบปฏิบัติการกระสวยอวกาศ: ไม่ไม่อนุญาตการรั่วไหลของหน่วยความจำ
  • การพัฒนาอย่างรวดเร็วของรหัสพิสูจน์แนวคิด: การแก้ไขการรั่วไหลของหน่วยความจำทั้งหมดนั้นเป็นการเสียเวลา

และมีสเปกตรัมของสถานการณ์ระดับกลาง

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


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

1
ฉันไม่เชื่อเลย และการจัดการหน่วยความจำนั้นซับซ้อนกว่าการเขียนวิธีการที่สะอาด
ดัสตินเก็ตซ์

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

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

5

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

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

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


5

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

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

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

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


ฉลาด. โดยเฉพาะอย่างยิ่งตั้งแต่การรั่วไหลอยู่ในระหว่างการเริ่มต้นซึ่งหมายความว่ามันจะไม่สะสมมากกว่ารันไทม์ของแอปพลิเคชัน
Demi

5

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

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

หากใช้หน่วยความจำที่เกี่ยวข้องคุณจะไม่สามารถทำให้ว่างได้ก่อนที่โปรแกรมจะสิ้นสุด ไม่ว่าฟรีจะทำโดยโปรแกรมออกหรือโดยระบบปฏิบัติการไม่สำคัญ ตราบใดที่มีการบันทึกไว้ดังนั้นการเปลี่ยนแปลงนั้นจะไม่ทำให้เกิดการรั่วไหลของหน่วยความจำจริงและตราบใดที่ไม่มี C ++ destructor หรือฟังก์ชั่นการล้าง C ที่เกี่ยวข้องในภาพ ไฟล์ที่ไม่ปิดอาจถูกเปิดเผยผ่านFILEวัตถุที่รั่วแต่ fclose () ที่หายไปอาจทำให้บัฟเฟอร์ไม่ได้ถูกลบทิ้ง

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

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


ว้าว ... ใครบางคนที่รู้ว่าหน่วยความจำรั่วคืออะไร
468 Simon Buchan

4

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

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

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

ดังนั้นหากคุณมีการรั่วไหล - ประเมินผลกระทบของมันสองวิธี

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

Foredecker


3. ผลกระทบต่อการบำรุงรักษาซอฟต์แวร์
peterchen

3

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

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


3

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

KIV


3

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


3

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

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

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

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

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

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


2

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


2

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

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

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


2

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


ในกรณีนั้นผลกระทบของการรั่วไหลของหน่วยความจำจะเปลี่ยนไปและคุณต้องประเมินลำดับความสำคัญของการเสียบปลั๊กอีกครั้ง
John Dibling

@ จอห์น: อย่างน้อยคุณควรบันทึกการรั่วไหล ถึงกระนั้นฉันก็ยังไม่ไว้ใจใครสักคนที่จะไม่เพิกเฉยความคิดเห็นที่กระพริบสีแดงขนาดใหญ่และคัดลอกและวางรหัสรั่วอย่างไรก็ตาม ฉันไม่ต้องการให้ใครบางคนสามารถทำสิ่งนั้นได้ตั้งแต่แรก
tloach

2

ฉันจะตอบไม่

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

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


2

ในอดีตมันมีความสำคัญกับระบบปฏิบัติการบางระบบในบางกรณี กรณีขอบเหล่านี้อาจมีอยู่ในอนาคต

นี่คือตัวอย่างใน SunOS ในยุค Sun 3 มีปัญหาหากกระบวนการใช้ exec (หรือมากกว่านั้นคือ fork และจากนั้นดำเนินการ) กระบวนการใหม่ที่ตามมาจะสืบทอดสืบทอดหน่วยความจำแบบเดียวกับพาเรนต์และไม่สามารถหดได้ . หากกระบวนการหลักจัดสรรหน่วยความจำ 1/2 กิ๊กและไม่ปล่อยให้ว่างก่อนการเรียก exec กระบวนการลูกจะเริ่มใช้ 1/2 กิกะไบต์เดียวกันนั้น (แม้ว่าจะไม่ได้ถูกจัดสรร) พฤติกรรมนี้แสดงได้ดีที่สุดโดย SunTools (ระบบหน้าต่างเริ่มต้น) ซึ่งเป็นหมูหน่วยความจำ แอพทุกตัวที่วางไข่ถูกสร้างขึ้นด้วย fork / exec และสืบทอด SunTools footprint เติมพื้นที่สว็อปอย่างรวดเร็ว


2

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


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

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

+1 ถือว่าเหมือนข้อผิดพลาดอื่น ๆ (ไม่ได้หมายความว่า "การแก้ไขทันที" ในหนังสือของฉัน แต่ "ความต้องการที่จะ befixed" สำหรับการตรวจสอบ)
peterchen

2

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

คุณทำอะไรกับโปรแกรมเซิร์ฟเวอร์ที่ออกแบบมาเพื่อไม่ให้ออกจากระบบ?

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

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

ทำความสะอาดตัวเอง Yo momma ไม่ทำงานที่นี่อีกแล้ว


ฉันทำงานกับโปรแกรมเซิร์ฟเวอร์ที่ใช้กระบวนการโดยไม่ได้ตั้งใจมากกว่าเธรดดังนั้นการรั่วไหลของหน่วยความจำและการแบ่งส่วนทำให้เกิดความเสียหาย จำกัด
บาง

แนวทางที่น่าสนใจ ฉันจะกังวลเล็กน้อยเกี่ยวกับกระบวนการที่ล้มเหลวในการออกและดำเนินการต่อเพื่อเพิ่มหน่วยความจำ
EvilTeach

2

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

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

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

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

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