ฉันจะป้องกันไม่ให้ Linux หยุดการทำงานเมื่อหน่วยความจำไม่เพียงพอได้อย่างไร


25

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

ฉันจะป้องกันสิ่งนี้ในอนาคตได้อย่างไร อย่างน้อยก็ไม่สามารถทำให้แกนตอบสนองหรือสิ่งที่กำลังทำงานอยู่ได้


คำตอบ:


15

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

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

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

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

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


2
น่าเสียดายที่ "อย่าทำสิ่งที่โง่" ไม่ช่วยผู้ใช้ที่เรียกใช้แอปพลิเคชันที่ใช้หน่วยความจำเช่น Chrome (ดูปัญหา134612 , 393395 )
Dan Dascalescu

1
@DanDascalescu และไม่ชัดเจนว่าคุณกำลังทำอะไรโง่ ๆ เครื่องของฉันหยุดทำงานเมื่อวันก่อนเพราะฉันเปลี่ยน "UNION" ในแบบสอบถาม SQLite (ซับซ้อน) เป็น "UNION ALL"
Michael

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

8

ดังกล่าวข้างต้นในความคิดเห็นโดย Tronic มันเป็นไปได้ที่จะโทร OOM ฆ่า (จากฆาตกรหน่วยความจำ) โดยตรงโดยการรวมกันแป้นพิมพ์-SysRqF

SysRqมักจะรวมPrtScคีย์ภายในคีย์บนแป้นพิมพ์

OOM-killer ฆ่ากระบวนการบางอย่าง (-es) และระบบจะตอบสนองอีกครั้ง การเข้าถึงโดยตรงไปยัง OOM-killer อาจไม่ได้เปิดใช้งานโดยค่าเริ่มต้นโปรดชำระเงินคำถามนี้เพื่อค้นหาวิธีตรวจสอบสถานะและ / หรือเปิดใช้งาน

PS: สิ่งนี้ช่วยฉันได้มาก ฉันเห็นด้วยกับความเห็นว่านี่เป็นคำแนะนำที่มีประโยชน์ที่สุดเกี่ยวกับปัญหานั้นถ้ามันเกิดจาก Chrome หรือซอฟต์แวร์โลภหน่วยความจำใด ๆ แต่คุณต้องจำไว้ว่า OOM-killer สามารถฆ่ากระบวนการที่สำคัญบางอย่างใช้อย่างระมัดระวัง


1

ปัญหานี้เป็นปัญหาที่รู้จักกันมาตั้งแต่ปี 2007 - เห็นแช่แข็งระบบการใช้งานหน่วยความจำสูง

ในสถานการณ์นี้ Windows จะแสดงกล่องโต้ตอบเตือนผู้ใช้ให้ปิดแอปพลิเคชั่นอย่างน้อยหนึ่งรายการ


0

หากคุณรู้สึกว่าต้องการคอมไพล์เคอร์เนลใหม่คุณสามารถลองแก้ไขจากEDITส่วนของคำถามนี้ได้ที่: /programming//q/52067753/10239615
มันไม่ได้ขับไล่Active(file)หน้าระหว่างความดันหน่วยความจำสูงและทำให้ OOM-killer เพื่อเรียกใช้งานเกือบจะในทันทีเนื่องจากเคอร์เนลไม่จำเป็นต้องใช้เวลานานอีกต่อไปในการอ่านดิสก์จากโค้ดเพจของโพรเซสที่เรียกใช้ทุกกระบวนการที่ก่อให้เกิดระบบแช่แข็ง


-1

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

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


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

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

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

@ AntonisChristofides: ฉันไม่แน่ใจว่าสิ่งที่คุณคิดว่าบทเรียน Takeaway จากที่เป็น วิธีแก้ปัญหาของคุณนั้นแย่มากเพราะมันทำให้ประสิทธิภาพการทำงานลดลงเนื่องจากไม่สามารถที่จะกำจัดหน้าที่สกปรกที่เข้าถึงได้ยากจากหน่วยความจำทางกายภาพมันไม่ได้แก้ปัญหาพื้นฐานและคุณเสี่ยงต่อการที่ OOM killer อาจฆ่ากระบวนการสำคัญ คุณไม่ต้องเผชิญกับอันตรายใด ๆ ที่ฉันได้รับคำเตือน แต่คุณก็ยังมีความเสี่ยงอยู่เพราะคุณไม่มีการแลกเปลี่ยน
David Schwartz

8
ไม่ว่าจะมีการสลับหรือไม่ก็ยังคงค้างก่อนที่ OOM killer จะทำงานโดยอัตโนมัติ นี่เป็นข้อผิดพลาดเคอร์เนลที่ควรได้รับการแก้ไข (เช่นเรียกใช้ OOM killer ก่อนหน้านี้ก่อนที่จะวางดิสก์แคชทั้งหมด) น่าเสียดายที่ผู้พัฒนาเคอร์เนลและคนอื่น ๆ จำนวนมากไม่สามารถมองเห็นปัญหาได้ คำแนะนำทั่วไปเช่นปิดการใช้งาน / เปิดใช้งานการซื้อ RAM เพิ่มเติมเรียกใช้กระบวนการน้อยลงตั้งค่าขีด จำกัด และอื่น ๆ ไม่ได้แก้ไขปัญหาพื้นฐานที่การจัดการหน่วยความจำต่ำของเคอร์เนลดูดลูกอูฐ ในขณะเดียวกันฉันขอแนะนำให้เรียกใช้ OOM killer ด้วยตนเอง (SysRq-F) เมื่อระบบค้างเพราะจะทำให้การกู้คืนเร็วขึ้น
Tronic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.