การจัดเรียงข้อมูล RAM / OOM ล้มเหลว


11

คำถามนี้มีความยาวพอสมควรดังนั้นฉันจะถามคำถามที่อยู่ด้านบนและจากนั้นผ่านวิธีการของฉันในการตอบคำถาม:

  1. ไม่ (ใช้ Busybox) rm ไม่ทำงานเนื่องจากมี RAM ต่อเนื่องไม่เพียงพอหรือไม่
  2. ถ้าเป็นเช่นนั้นจะมีวิธีที่มีน้ำหนักเบาในการจัดเรียงข้อมูล DMA โดยไม่ต้องรีสตาร์ทระบบหรือไม่?
  3. ถ้าไม่เกิดอะไรขึ้น ฉันจะป้องกันไม่ให้เกิดขึ้นในอนาคตได้อย่างไร

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

หลังจากนี้ฉันสังเกตเห็นคำสั่งเชลล์ของฉันมากขึ้นเรื่อย ๆ ไม่ได้ทำงานตามที่คาดไว้

ฉันจะเริ่มต้นด้วยการส่งออกจากdmesgหลังจาก rm ล้มเหลวในการดำเนินการอย่างถูกต้อง:

การจัดสรรความยาว 61440 จากกระบวนการ 6821 (rm) ล้มเหลว

DMA ต่อซีพียู:

CPU 0: hi: 0, btch: 1 usd: 0

Active_anon: 0 active_file: 1 inactive_anon: 0 inactive_file: 0 ไม่แน่นอน: 6 สกปรก: 0 writeback: 0 ไม่เสถียร: 0 ฟรี: 821 แผ่น: 353 แมป: 0 pagetables: 0 เด้ง: 0

ฟรี DMA: 3284kB ขั้นต่ำ: 360kB ต่ำ: 448kB สูง: 540kB active_anon: 0kB ไม่ได้ใช้งาน: 0kB active_file: 4kB อยู่ในสถานะ active_file: 0kB ไม่สามารถคาดเดาได้: 24kB หน้าปัจจุบัน: 8128kB pages_scanned: 0 all_unreclaimable ไม่

lowmem_reserve []: 0 0 0

DMA: 31 * 4kB 47 * 8kB 42 * 16kB 64 * 32kB 1 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 0 * 4096kB = 3284kB

14 หน้า pagecache ทั้งหมด

ไม่สามารถจัดสรร RAM สำหรับข้อมูลกระบวนการได้ errno 12

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

จากนั้นฉันทำการตรวจสอบทางคณิตศาสตร์อย่างรวดเร็วและรู้ตัวว่าโปรแกรมควรจะสามารถทำงานในสล็อตหน่วยความจำต่อเนื่อง 64kB แต่เพียงผู้เดียว Rm กำลังร้องขอ 61440 ไบต์ (60kB)

ฉันทำได้ดีมาก "manual defrag" และรีบูตระบบ เมื่อฉันรีบูทระบบฉันจะส่งออก / proc / buddyinfo:

Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0

ซึ่งฉันสงสัยว่าแผนที่เพื่อ:

  • 2 x 4 kB
  • 8 x 8 kB
  • 3 x 16 kB
  • 12 x 32 kB
  • 1 x 128 kB
  • 1 x 512 kB

แต่ถ้ามีผลรวมของรายการด้านบนค่าจะไม่ตรงกับเอาต์พุตของ/ proc / meminfo :

MemTotal:           6580 kB
MemFree:            3164 kB
Buffers:               0 kB
Cached:              728 kB
SwapCached:            0 kB
Active:              176 kB
Inactive:            524 kB
Active(anon):          0 kB
Inactive(anon):        0 kB
Active(file):        176 kB
Inactive(file):      524 kB`
Unevictable:           0 kB
Mlocked:               0 kB
MmapCopy:            844 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:             0 kB
Mapped:                0 kB
Slab:               1268 kB
SReclaimable:        196 kB
SUnreclaim:         1072 kB
PageTables:            0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        3288 kB
Committed_AS:          0 kB
VmallocTotal:          0 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB

เพื่อสรุปคำถามของฉันคือ:

  1. rm ไม่ทำงานเพราะมี RAM ไม่ต่อเนื่องเพียงพอหรือไม่
  2. ถ้าเป็นเช่นนั้นจะมีวิธีที่มีน้ำหนักเบาในการจัดเรียงข้อมูล DMA โดยไม่ต้องรีสตาร์ทระบบหรือไม่?
  3. ถ้าไม่เกิดอะไรขึ้น ฉันจะป้องกันไม่ให้เกิดขึ้นในอนาคตได้อย่างไร

ฉันใช้ XPort Pro (8MB, Linux OS) ของ Lantronix ที่ใช้ uClinux เวอร์ชั่น 2.6.30 เชลล์ที่ใช้อยู่นั้นเงียบ


จุดเล็กน้อย: คุณเหลือ 1 x 2048 kB จากรายการหน่วยความจำของคุณ หากคุณรวมถึงผลรวมนั้นคือ 3192 kB ซึ่งอยู่ใกล้กับ 3164 kB ที่อยู่ในรายการ / proc / meminfo
Alex Selby

คำตอบ:


11

สำหรับคำถามที่ 2 ของคุณ (การจัดเรียงข้อมูลบนหน่วยความจำ) ให้อ้างอิงจากhttps://www.kernel.org/doc/Documentation/sysctl/vm.txt :

compact_memory

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

นี่ก็หมายความว่าคำสั่งดังต่อไปนี้ (ดำเนินการด้วยสิทธิ์ root และถ้าตัวเลือกเคอร์เนลดังกล่าวเปิดใช้งาน)

echo 1 > /proc/sys/vm/compact_memory

ควรบอกเคอร์เนลให้พยายามจัดเรียงข้อมูลหน่วยความจำให้มากที่สุด ระวังเช่นในบางรุ่น RHEL6 นี้สามารถทำให้เคอร์เนลผิดพลาด ...


1
ขอบคุณที่ใช้เวลากลับมาและแสดงความคิดเห็นกับคำถามเก่า ๆ !
OldTinfoil

7

ใช้เวลาสักครู่ แต่ฉันคิดว่าฉันจะหยุดตอบจนกว่าฉันจะตอบคำถามย่อยทั้งสามข้อของฉัน

ก่อนที่ฉันจะเริ่มฉันจะพูดถึงคำที่ถูกต้องเมื่อมันมาถึงหน่วยความจำการทำงาน "de-fragmenting" เรียกว่า "การกระชับ" หน่วยความจำการทำงาน

1. rm ไม่ทำงานเนื่องจาก RAM ไม่ต่อเนื่องเพียงพอหรือไม่

ฉันถูกต้องในบทสรุปของฉัน - rm ไม่ได้ดำเนินการเพราะมี RAM ติดกันไม่เพียงพอ ระบบได้รับ RAM และแยกส่วนมันทำให้ไม่สามารถขอคืนได้

2. ถ้าเป็นเช่นนั้นจะมีวิธีที่มีน้ำหนักเบาในการจัดระเบียบ DMA - โดยไม่ต้องรีสตาร์ทระบบหรือไม่?

ปรากฎว่าไม่มีวิธีการบีบอัดหน่วยความจำสั้น ๆ จากการรีสตาร์ทระบบฝังตัว ในกรณีของระบบ MMU-less การป้องกันคือชื่อของเกม

ส่วนหนึ่งของฉันใคร่ครวญถ้าเป็นไปได้ที่จะแฮ็กเคอร์เนล linux เลียนแบบ MMU ในซอฟต์แวร์ ฉันคิดว่ามันเป็นไปได้ใครจะทำมันแล้ว ฉันไม่สามารถจินตนาการถึงแนวคิดใหม่ทั้งหมดได้)

3. ฉันจะป้องกันไม่ให้เกิดขึ้นในอนาคตได้อย่างไร

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

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

อย่างไรก็ตามฉันขอแนะนำให้หลีกเลี่ยงเชลล์หากเป็นไปได้สำหรับระบบ MMU-less -

( คำถามจะเกิดอะไรขึ้นถ้าคุณดำเนินการls -la /path/to/directory/ | grep file-i-seek)

( คำตอบ : มันเริ่มต้นกระบวนการย่อยใหม่)

หากคุณต้องการที่จะใช้บางส่วนของฟังก์ชั่นเชลล์สคริปต์หลักในโปรแกรม C ของคุณผมขอแนะนำให้ตรวจสอบจากรหัสที่มาใช้ในBusyBox โอกาสที่คุณจะใช้ C ในระบบฝังตัวของคุณ ..


ขอบคุณที่สละเวลากลับมาและแบ่งปันสิ่งที่คุณค้นพบ
คาเลบ

3
[ฉันรู้ว่านี่เก่า] การเลียนแบบ MMU นั้นยาก ... หากไม่มี MMU ทุกโปรแกรมจะใช้ที่อยู่ทางกายภาพโดยตรงตามที่ปรากฏบนบัสหน่วยความจำ คุณสามารถเลียนแบบได้ แต่คุณต้องสกัดกั้นการเข้าถึงหน่วยความจำทุกครั้ง (เช่นเดียวกับ MMU จริง) ประสิทธิภาพจะแย่มาก อีกวิธีหนึ่งคุณสามารถใช้ตัวชี้ทางอ้อม (เช่นเดียวกับ Mac OS Classic เรียกพวกเขาว่า "จัดการ") แต่จากนั้นคุณมี API ที่ยากอย่างสมบูรณ์และตัวที่ยากมากในการเผชิญกับการชำระล่วงหน้า (Mac OS Classic ใช้มัลติทาสก์แบบร่วมมือ) .
Derobert

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