เหตุใด QEMU จึงไม่สามารถจัดสรรหน่วยความจำได้หากแคชแคชใหญ่เกินไป


9

ถ้าฉันใช้เครื่องของฉัน [Ubuntu 16.04 64 บิต, เคอร์เนล 4.4] ชั่วครู่หนึ่ง QEMU ต้องการเคอร์เนลแคชที่จะถูกลบไม่เช่นนั้นจะไม่สามารถจัดสรร RAM ได้

ทำไมมันเกิดขึ้น

นี่คือการรันตัวอย่าง:

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        5427        3690          56        5931        4803
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1799        9446          56        3803        9414
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1502       10819          56        2727       10784
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
# Now QEMU starts

4
เพราะคุณไม่ได้มีการแลกเปลี่ยนใด ๆ
Michael Hampton

คำตอบ:


19

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

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


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

2
@ hexafraction เพียงเดา: อาจเป็นไปได้ในทางเทคนิค (แต่อาจเพิ่มความซับซ้อนที่สำคัญไม่แน่ใจ) แต่เคอร์เนล devs อาจจะยืนยันว่าไม่จำเป็นต้องมีคุณสมบัตินั้นเพราะปัญหาเดียวที่แก้ได้เกิดจากการไม่มี swap ซึ่ง ยังทำให้เกิดปัญหาอื่น ๆ ทั้งหมดนี้ได้รับการแก้ไขหากคุณเพียงแค่เปิดใช้งานการสลับและปล่อยให้เคอร์เนลทำการจัดการหน่วยความจำในแบบที่มันใช้งานได้ดีอยู่แล้ว
mtraceur

1
@ hexafraction เคอร์เนลไม่มีความคิดว่าเป็นสิ่งที่เหมาะสมที่จะทำ สำหรับแอปพลิเคชั่นบางตัวที่ไม่สมเหตุสมผลดังนั้นจึงไม่ใช่นโยบายทั่วไป QEMU เลือกที่จะไม่ทำเช่นนั้น
David Schwartz

2
@hexafraction จริงๆคุณจะต้องการที่จะรอ 30 วินาที - หรือหลายนาที - สำหรับคุณmalloc()โทรไปอาจจะพบว่าหน่วยความจำเพียงพอหรือไม่
Michael Hampton

3
@hexafraction ลองคิดดูด้วยวิธีนี้ หากเคอร์เนลมีคุณสมบัตินี้ตามหลักวิชาการในการบล็อกชั่วขณะหาก malloc จะล้มเหลวเป็นอย่างอื่นจะไม่มีวิธีใดที่จะบรรลุพฤติกรรมปัจจุบันโดยไม่ต้องมี API เพิ่มเติม ในทางตรงกันข้ามการใช้งานในปัจจุบันอนุญาตให้ซอฟต์แวร์ที่ต้องการรอและลองอีกครั้งในขณะที่ลอง malloc อีกครั้งในลูปช้าจนกว่าจะพอใจ
Vality
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.