คุณจะทำอย่างไรเมื่อmalloc
ส่งกลับข้อยกเว้น 0 หรือข้อผิดพลาดการส่งใหม่ เพียงหยุดหรือพยายามเอาตัวรอดจากเงื่อนไขของ OOM / บันทึกงานของผู้ใช้
คุณจะทำอย่างไรเมื่อmalloc
ส่งกลับข้อยกเว้น 0 หรือข้อผิดพลาดการส่งใหม่ เพียงหยุดหรือพยายามเอาตัวรอดจากเงื่อนไขของ OOM / บันทึกงานของผู้ใช้
คำตอบ:
ฉันจะหลีกเลี่ยง OOM เช่นเดียวกับการหลีกเลี่ยงความผิดพลาด
หลีกเลี่ยงการทำงานชิ้นใหญ่ ๆ (และจัดสรรหน่วยความจำขนาดใหญ่) ทันที เก็บข้อมูลบนดิสก์ไว้วางใจแคชดิสก์ของระบบปฏิบัติการและใช้งาน IO ที่แมปหน่วยความจำให้มากที่สุดเท่าที่จะทำได้และทำงานบนข้อมูลเพียงส่วนน้อยในแต่ละครั้ง หากข้อมูลจำนวนมากจำเป็นต้องออนไลน์ (ให้บริการที่มีเวลาแฝงต่ำ) ให้เก็บไว้ในหน่วยความจำในหลาย ๆ เครื่องเช่นเดียวกับที่ บริษัท เครื่องมือค้นหารายใหญ่ทำ หรือซื้อ SSD
คนส่วนใหญ่ที่ตอบคำถามนี้อาจไม่เคยทำงานกับระบบฝังตัวซึ่ง malloc ที่ส่งคืนค่า 0 เป็นความเป็นไปได้ที่แท้จริง ในระบบที่ฉันใช้งานอยู่ในปัจจุบันมี RAM ทั้งหมด 4.25K ไบต์ (นั่นคือ 4352 ไบต์) ฉันจัดสรร 64 ไบต์สำหรับสแต็กและปัจจุบันมี 1600 ไบต์ฮีป เมื่อวานนี้ฉันเพิ่งดีบักฮีปเดินฮีปเพื่อให้ฉันสามารถติดตามการจัดสรรและการเพิ่มหน่วยความจำ heap walk ใช้บัฟเฟอร์ที่จัดสรรแบบสแตติกขนาดเล็ก (30 ไบต์) เพื่อส่งออกไปยังพอร์ตอนุกรม มันจะถูกปิดสำหรับรุ่นที่วางจำหน่าย
เนื่องจากนี่เป็นผลิตภัณฑ์สำหรับผู้บริโภคจึงไม่ควรเรียกใช้หน่วยความจำไม่เพียงพอเมื่อมีการเปิดตัวผลิตภัณฑ์ ฉันแน่ใจว่ามันจะอยู่ระหว่างการพัฒนา ไม่ว่าในกรณีใด ๆ สิ่งที่ฉันทำได้คือส่งเสียงบี๊บสองสามครั้งและบังคับให้รีบูต
เพื่อความซื่อสัตย์ในทุกโครงการที่ฉันทำ (โปรดจำไว้ว่าฉันยังไม่ได้ทำงานเลย) ฉันไม่เคยคิดเลยว่ามันจะเกิดขึ้นได้และดังนั้นฉันคิดว่าโปรแกรมของฉันจะตายอย่างรวดเร็วมาก
นอกจากนี้การจัดการ OOM จะต้องให้คุณจัดสรรทรัพยากรล่วงหน้าเพื่อแสดงข้อความแสดงข้อผิดพลาดหรือบันทึกทุกอย่างซึ่งอาจไม่สะดวก
ฉันรู้สึกว่าวันนี้หน่วยความจำมีราคาน้อยกว่าถั่วลิสงมันไม่ใช่สิ่งที่ควรเกิดขึ้นบ่อย ในตอนเช้าของหน่วยความจำที่ได้รับการป้องกันและก่อนหน้านี้อาจเป็นเรื่องที่น่ากังวล ข้อผิดพลาด OOM ข้อเดียวที่ฉันเคยเห็นมาจากรหัสที่ bugged
การตรวจสอบรหัสที่ส่งคืน malloc นั้นเป็นสิ่งที่ไม่มีประโยชน์เลย
ระบบปฏิบัติการที่ทันสมัยหน่วยความจำ overcommit: พวกเขาให้กระบวนการหน่วยความจำมากกว่าที่เป็นจริง หน่วยความจำที่กระบวนการของคุณได้รับนั้นเสมือนจริงทั้งหมดจะถูกแมปเข้ากับหน้า zeroed-out เดียว
ไม่ใช่จนกว่าคุณจะเขียนลงในหน่วยความจำว่ามีการจัดสรรเพจที่มีอยู่จริงและไม่ซ้ำใครสำหรับกระบวนการของคุณ หากการจัดสรรนี้ล้มเหลวเคอร์เนลจะยุติกระบวนการ (อาจเป็นของคุณ!) ในความพยายามที่จะค้นหาหน่วยความจำ ณ จุดนี้คุณไม่สามารถทำอะไรได้อีกแล้ว
เว้นแต่ว่าคุณกำลังพัฒนาสำหรับระบบฝังตัวระบบเรียลไทม์หรือระบบที่สำคัญมากที่ความล้มเหลวอาจทำให้เสียชีวิตหรือพันล้านดอลลาร์ ... จากนั้นอาจไม่คุ้มค่าทางการเงินที่จะต้องกังวลเกี่ยวกับสภาพความจำที่ไม่เพียงพอ
ในกรณีส่วนใหญ่มีเพียงเล็กน้อยที่สามารถทำได้เมื่อคุณออกจากหน่วยความจำหมดเนื่องจากไม่มีหน่วยความจำในการสร้างวัตถุใหม่หรือทำงานใด ๆ ที่อาจทำอะไรบางอย่าง คุณต้องชั่งน้ำหนักค่าใช้จ่ายของแอพที่จัดการ OOM กับผลประโยชน์ที่คุณได้รับจากการทำมัน
ฉันมักจะตรวจสอบข้อผิดพลาด หากบางสิ่งส่งกลับเงื่อนไขข้อผิดพลาดก็จะต้องมีการจัดการโดยโปรแกรมของคุณ แม้ว่าจะเป็นข้อความที่ระบุว่า "หน่วยความจำไม่พอ!" จะดีกว่า "การละเมิดการเข้าถึง", "การทิ้งหลัก" หรืออะไรก็ตาม หนึ่งคือเงื่อนไขข้อผิดพลาดที่คุณจัดการอีกประการหนึ่งคือข้อผิดพลาด และผู้ใช้จะรับรู้มันเช่นกัน
สำหรับกรณีเฉพาะของคุณคุณสามารถลองย้อนกลับการดำเนินการปลดปล่อยทรัพยากรที่คุณได้จัดสรรไว้จนกว่าจะถึงจุดที่ล้มเหลวรายงานข้อผิดพลาดและดำเนินการต่อไป (บางทีเมื่อคุณพยายามที่จะออกจากแอปพลิเคชัน ตัวเลือกเพื่อออกทันที) ด้วยวิธีนี้ผู้ใช้สามารถตัดสินใจว่าจะทำอย่างไรหรือพยายามเพิ่มหน่วยความจำบางส่วนโดยเล่นซอปิดไฟล์ ฯลฯ แน่นอนว่าคุณสามารถจัดการกับสถานการณ์ได้อย่างไรนั้นขึ้นอยู่กับโปรแกรมของคุณเป็นอย่างมาก - โปรแกรมที่ไม่ควร เป็นแบบโต้ตอบอาจเพียงแค่ต้องบันทึกข้อผิดพลาดและออกหรือดำเนินการต่อ