คุณจัดการกับเงื่อนไขหน่วยความจำไม่เพียงพอหรือไม่?


9

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


4
เกี่ยวข้องกับ Stackoverflow stackoverflow.com/questions/763159/…
ysolik

11
โอ๊ะ ฉันอ่านต่อไปว่า "ออกมาน่า" ฉันคิดว่ามีวิดีโอเกมมากเกินไปในอดีต :)
Adam Lear

คำตอบ:


4

ฉันจะหลีกเลี่ยง OOM เช่นเดียวกับการหลีกเลี่ยงความผิดพลาด

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


เห็นได้ชัดว่าสิ่งนี้เหมาะสมที่สุด
mbq

2
มีการถกเถียงกันอย่างมากเกี่ยวกับวิธีการจัดการ OOM ได้อย่างงดงาม (RAII, ยกเว้นความปลอดภัย, blah ... ) แต่เมื่อฉันรู้ว่าในระบบมัลติเธรดที่มีโมดูลแบบไดนามิกหลาย (บางส่วนจากบุคคลที่สาม) แม้ว่าเธรดของคุณจะไม่ เกิดข้อผิดพลาดมีช่วงเวลาที่โชคร้ายที่ทุกเธรดจะเห็น OOM หากแม้แต่คนเดียวตัดสินใจที่จะเดินหน้าต่อไปคุณจะไม่สามารถทำอะไรได้นอกจากเป็นพยาน
rwong

13

คนส่วนใหญ่ที่ตอบคำถามนี้อาจไม่เคยทำงานกับระบบฝังตัวซึ่ง malloc ที่ส่งคืนค่า 0 เป็นความเป็นไปได้ที่แท้จริง ในระบบที่ฉันใช้งานอยู่ในปัจจุบันมี RAM ทั้งหมด 4.25K ไบต์ (นั่นคือ 4352 ไบต์) ฉันจัดสรร 64 ไบต์สำหรับสแต็กและปัจจุบันมี 1600 ไบต์ฮีป เมื่อวานนี้ฉันเพิ่งดีบักฮีปเดินฮีปเพื่อให้ฉันสามารถติดตามการจัดสรรและการเพิ่มหน่วยความจำ heap walk ใช้บัฟเฟอร์ที่จัดสรรแบบสแตติกขนาดเล็ก (30 ไบต์) เพื่อส่งออกไปยังพอร์ตอนุกรม มันจะถูกปิดสำหรับรุ่นที่วางจำหน่าย

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


2
ฟังก์ชั่นการใช้งานที่เหมาะสมภายในพื้นที่ขนาดเล็กนั้นช่างน่าอัศจรรย์ ... มันเป็นรูปแบบของศิลปะอย่างบอนไซ
ร. ง.

6
หลายโครงการในระบบฝังตัวนั้นห้ามการจัดสรรหน่วยความจำแบบไดนามิก กรณีเดียวของ OOM ยังคงมีมากเกินไป
mouviciel

คุณพูดถูก แต่โดยเฉพาะอย่างยิ่งกับประโยคแรกของคุณ: สิ่งนี้ส่วนใหญ่ไม่เกี่ยวข้องกับนักพัฒนาส่วนใหญ่โชคดี
Konrad Rudolph

4

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

นอกจากนี้การจัดการ OOM จะต้องให้คุณจัดสรรทรัพยากรล่วงหน้าเพื่อแสดงข้อความแสดงข้อผิดพลาดหรือบันทึกทุกอย่างซึ่งอาจไม่สะดวก

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


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

2

การตรวจสอบรหัสที่ส่งคืน malloc นั้นเป็นสิ่งที่ไม่มีประโยชน์เลย

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

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


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

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

แต่ฉันสามารถลองให้ OOM ว่างหน่วยความจำแล้วลองจัดสรรอีกครั้งและทำต่อไป ฉันมีความประทับใจที่ malloc / ใหม่ไม่รอให้สิ่งนี้เกิดขึ้น
mbq

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

2
ฉันค่อนข้างแน่ใจว่า windows จะไม่ทับซ้อนกัน สามารถคอมมิตมากกว่า RAM แต่ไม่เกิน RAM + swapfile
CodesInChaos

2

เว้นแต่ว่าคุณกำลังพัฒนาสำหรับระบบฝังตัวระบบเรียลไทม์หรือระบบที่สำคัญมากที่ความล้มเหลวอาจทำให้เสียชีวิตหรือพันล้านดอลลาร์ ... จากนั้นอาจไม่คุ้มค่าทางการเงินที่จะต้องกังวลเกี่ยวกับสภาพความจำที่ไม่เพียงพอ

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


ระบบเรียลไทม์ไม่จำเป็นต้องตรวจสอบเพิ่มเติมเกี่ยวกับความล้มเหลวของ malloc มากกว่าระบบอื่น ๆ
zneak

@zneak - ไม่จริง ระบบแบบเรียลไทม์จะต้องสามารถคาดเดาได้และหน่วยความจำไม่สามารถคาดการณ์ได้เว้นแต่คุณจะวางแผนเป็นพิเศษ
Erik Funkenbusch

แล้วคุณจะทำอะไรอีกเมื่อคุณโจมตี OOM?
zneak

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

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

1

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

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

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