linux ไม่ได้ใช้ swap แต่ OOM killer ทำงาน


1

ฉันได้รับปัญหานี้มานานแล้วและฉันไม่สามารถหาได้โดยทั่วไประบบ linux (32 บิต 3.2.6-3.fc16.i686.PAE) ของฉันปฏิเสธที่จะใช้การแลกเปลี่ยน เมื่อฉันวิ่ง

$ tail /dev/zero
tail: memory exhausted

มันไม่หันไปใช้การแลกเปลี่ยนเลย .. มันเพิ่งตายหลังจากใช้ RAM จริง นี่คือรายละเอียดที่เกี่ยวข้อง

$ free -m
             total       used       free     shared    buffers     cached
Mem:          8076       4652       3423          0        123        543
-/+ buffers/cache:       3985       4090
Swap:         8192        116       8076


$ cat /proc/sys/vm/swappiness 
60

$ ulimit -m
unlimited

$ cat /proc/sys/vm/overcommit_ratio
50

$ cat /proc/sys/vm/overcommit_memory 
0

ฉันพยายามตั้งค่าเป็น 1:

# sysctl vm.overcommit_memory=1
vm.overcommit_memory = 1


$ cat /proc/sys/vm/overcommit_memory 
1

และลองอีกครั้งผลลัพธ์เดียวกัน ความคิดใด ๆ


คำตอบนี้ช่วยได้ไหม? superuser.com/questions/561617/…
tink

@tink ไม่แน่ใจว่าทำไมฉันไม่เห็นความคิดเห็นของคุณก่อนหน้านี้ แต่ฉันจะตรวจสอบการเชื่อมโยงและเห็นเส้นและเพียงแค่การตรวจสอบในระบบของฉันมันถูกกำหนดให้vm.overcommit_memory=1 vm.overcommit_memory=0ฉันเพิ่งเปลี่ยนไปและจะอัปเดตคำถามนี้เมื่อฉันรู้ว่านั่นจะหลอกลวงหรือไม่ ขอบคุณ!
บ้า

@ ลิงค์ดีฉันเพิ่งลองtail /dev/zeroและมันใช้งานไม่ได้ การแลกเปลี่ยนยังไม่ถูกใช้ แต่freeบอกให้ฉันทราบว่าการแลกเปลี่ยนเปิดอยู่! โอ๊ะ
บ้า

คำตอบ:


0

มันเป็น Linux แบบ 32 บิตดังนั้นจึงไม่มีวิธีจัดสรรหน่วยความจำ 4GiB สำหรับแอปพลิเคชันมากกว่าเพราะจะทำให้พื้นที่ที่อยู่หมดลง คุณมี RAM 8GiB และส่วนใหญ่ว่างดังนั้น 4096 MiB สามารถจัดสรรโดยไม่ต้องใช้การสลับ


แต่ถ้าฉันมี RAM จริง 3GB และฉันtail /dev/zeroก็ยังคงกินต่อไปอย่างน้อย 1GB พิเศษที่ได้รับอนุญาตก่อนที่จะกดขีด จำกัด 4GB ที่คุณพูดถึงใช่มั้ย
บ้า

อาจ ... มันต้องเป็นระบบ 32 บิต พื้นที่แอดเดรสที่อนุญาตสูงสุดจริง ๆ นั้นน้อยกว่า 3GiB เนื่องจากเคอร์เนลระบบปฏิบัติการดังนั้นลองใช้กับเครื่องที่มี RAM 2GiB
ilkhd

2GB ฟรีจะทำงานด้วยเช่นกัน?
บ้า

ไม่แน่ใจ. ควร แต่ใน Linux คุณไม่เคยรู้ว่าคุณมีหน่วยความจำว่างเท่าไหร่
ilkhd

0

คำถามนี้ค่อนข้างเก่า แต่มีคำตอบง่ายๆ:

tailไอเอ็นจีจาก/dev/zeroไม่ได้ทำอะไรที่ดี ถ้าคุณเพียงต้องการกระแสด้วย null catไบต์ใช้

tail(พร้อมพารามิเตอร์เริ่มต้น) จะส่งคืน 10 บรรทัดสุดท้ายจากอาร์กิวเมนต์ เนื่องจาก/dev/zeroเป็นอุปกรณ์ตัวอักษรมันจะเริ่มอ่านข้อมูลจำนวนหนึ่งจนกว่าจะสิ้นสุด (ไฟล์ปกติจะถูกสแกนไปด้านหลัง) ข้อมูลการอ่านจะถูกเก็บไว้จนกว่าจะพบ 10 บรรทัดจากนั้นบรรทัดแรกจะถูกขับออกจากบัฟเฟอร์

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

โชคดีที่คุณอยู่ในระบบ 32 บิตและมีหน่วยความจำว่างมากมายดังนั้นหน่วยความจำที่มีอยู่ในกระบวนการเดียว (โดยทั่วไปคือ 2 GiB แต่อาจแตกต่างกันไปขึ้นอยู่กับการกำหนดค่าเคอร์เนล) หมดลงอย่างรวดเร็วและไม่มีการแลกเปลี่ยน คำสั่งถูกยกเลิก หากคุณลองใช้ระบบเดียวกันกับหน่วยความจำน้อยกว่าหรือพื้นที่ที่อยู่ที่ใหญ่กว่า (ระบบ 64- บิต) หางจะกินหน่วยความจำทั้งหมดที่จะได้รับเอาเคอร์เนลเพื่อสลับออกให้มากที่สุดและในที่สุดคุณก็จะยังคง รับข้อผิดพลาดในการจัดสรรหน่วยความจำ หรือเรียกใช้ OOM-killer แต่ก็ยังไม่มีโมฆะใน stdout


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