Pertanyaan ini cukup panjang, jadi saya akan mengajukan pertanyaan di atas dan kemudian melanjutkan metode saya untuk datang ke pertanyaan:
- Apakah (berbasis Busybox) rm tidak dijalankan karena tidak ada cukup RAM yang berdekatan?
- Jika demikian, apakah ada metode ringan defragging DMA - tanpa menggunakan sistem restart?
- Jika tidak, apa yang menyebabkannya? Bagaimana saya bisa mencegahnya terjadi di masa depan?
Setelah sistem pengujian kami berjalan cukup intensif selama beberapa hari terakhir - saya telnet ke sistem dan memeriksa hasil pengujian. Ketika saya datang untuk menghapus beberapa data, sistem mengembalikan baris perintah (seolah-olah perintah telah dijalankan dengan benar). Ketika saya datang untuk memeriksa direktori untuk set hasil yang lain, saya melihat file tersebut masih ada (menggunakan ls).
Setelah ini, saya perhatikan semakin banyak perintah shell saya tidak berfungsi seperti yang diharapkan.
Saya akan mulai dengan output dari dmesg setelah rm gagal dieksekusi dengan benar:
Alokasi dengan panjang 61440 dari proses 6821 (rm) gagal
DMA per-CPU:
CPU 0: hi: 0, btch: 1 usd: 0
Active_anon: 0 active_file: 1 inactive_anon: 0 inactive_file: 0 unevictable: 6 dirty: 0 writeback: 0 unstable: 0 free: 821 slab: 353 dipetakan: 0 pagetable: 0 bounce: 0
DMA gratis: 3284kB min: 360kB rendah: 448kB tinggi: 540kB aktif_anon: 0kB tidak aktif_anon: 0kB aktif_file: 4kB tidak aktif_file: 0kB tidak dapat ditangguhkan: 24kB sekarang: 8128kB halaman_memindai: 0 all_unreclaimable? tidak
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 * 2096kB 0 * 4096kB = 3284kB
14 total halaman pagecache
Tidak dapat mengalokasikan RAM untuk memproses data, errno 12
Awalnya, saya pikir saya tidak dapat menjalankan program di bagian terbesar dari memori yang berdekatan. Berarti DMA terlalu terfragmentasi dan saya harus menemukan cara untuk mendapatkan sistem untuk mendefrag memori.
Kemudian saya melakukan pemeriksaan matematika / kewarasan cepat dan menyadari bahwa program seharusnya bisa berjalan di slot memori berdekatan 64kB tunggal. Rm meminta 61440 byte (60kB).
Saya melakukan "defrag manual" lama yang baik dan mem-boot ulang sistem. Ketika saya reboot sistem saya output / proc / buddyinfo:
Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0
Yang saya duga peta untuk:
- 2 x 4 kB
- 8 x 8 kB
- 3 x 16 kB
- 12 x 32 kB
- 1 x 128 kB
- 1 x 512 kB
Tetapi jika seseorang menjumlahkan daftar nilai di atas, itu tidak cocok dengan output dari / 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
Untuk rekap, pertanyaan saya adalah:
- Apakah saya tidak menjalankan karena tidak ada cukup RAM yang berdekatan?
- Jika demikian, apakah ada metode ringan defragging DMA - tanpa menggunakan sistem restart?
- Jika tidak, apa yang menyebabkannya? Bagaimana saya bisa mencegahnya terjadi di masa depan?
Saya menggunakan Lantortix's XPort Pro (8MB, Linux OS) menjalankan uClinux versi 2.6.30. Shell yang digunakan diam.
Jawaban:
Pada pertanyaan Anda 2 (defragmenting memory), mengutip dari https://www.kernel.org/doc/Documentation/sysctl/vm.txt :
ini menyiratkan bahwa perintah berikut (dijalankan dengan hak akses root dan jika opsi kernel yang disebutkan di atas diaktifkan)
harus memberitahu kernel untuk mencoba mendefrag memori sebanyak mungkin. Hati-hati, mis. Pada beberapa versi RHEL6, ini dapat membuat kernel ...
sumber
Butuh sedikit waktu, tetapi saya pikir saya akan menunda menjawab sampai saya punya jawaban untuk semua 3 sub-pertanyaan saya.
Sebelum saya mulai, saya akan menyebutkan bahwa istilah yang benar ketika datang ke "de-fragmenting" memori kerja disebut dengan "memadatkan" memori kerja.
1. Apakah rm tidak dieksekusi karena tidak ada cukup RAM yang berdekatan?
Saya benar dalam kesimpulan saya - rm tidak mengeksekusi karena ada cukup RAM yang berdekatan. Sistem telah memperoleh RAM dan memecah-mecahnya, sehingga membuatnya tidak dapat diklaim kembali.
2. Jika demikian, apakah ada metode ringan defragging DMA - tanpa menggunakan sistem restart?
Ternyata tidak ada cara memadatkan memori, singkat untuk memulai ulang sistem tertanam. Dalam kasus sistem tanpa-MMU, pencegahan adalah nama permainan.
Sebagian dari saya merenungkan apakah mungkin untuk meretas kernel linux untuk meniru MMU dalam perangkat lunak. Saya pikir jika itu mungkin, seseorang pasti sudah melakukannya. Saya tidak bisa membayangkan itu konsep yang sama sekali baru;)
3. Bagaimana saya bisa mencegahnya terjadi di masa depan?
Untuk proyek ini, saya menggunakan cron untuk memulai program secara manual setiap kali diperlukan. Cara yang lebih baik untuk melakukan ini adalah dengan memanggil program saat start up, dan kemudian memaksa program untuk tidur sampai diperlukan. Dengan cara ini, memori tidak perlu dialokasikan pada setiap penggunaan. Sehingga mengurangi fragmentasi.
Pada iterasi pertama dari proyek, kami mengandalkan panggilan skrip shell saya untuk melakukan fungsi kritis (seperti rm). Kami tidak melihat perlunya menciptakan kembali roda jika tidak perlu.
Namun, saya akan merekomendasikan menghindari shell jika memungkinkan untuk sistem MMU-kurang -
( Pertanyaan , apa yang terjadi jika Anda mengeksekusi
ls -la /path/to/directory/ | grep file-i-seek
?)( Jawab : ini memulai subproses baru)
Jika Anda perlu menerapkan beberapa fungsionalitas skrip shell inti dalam program C Anda, saya sarankan memeriksa kode sumber yang digunakan dalam BusyBox . Kemungkinannya adalah Anda akan menggunakan C di sistem embedded Anda ..
sumber