この質問はかなり長いので、最初に質問をしてから、質問に来る方法を説明します。
この数日間、テストシステムがかなり集中的に実行された後、Telnetでシステムにアクセスし、テスト結果を確認しました。データを削除するようになったとき、システムはコマンドラインを返しました(コマンドが正しく実行されたかのように)。ディレクトリで別の結果セットを確認するようになったとき、ファイルがまだ存在しているのがわかりました(lsを使用)。
この後、シェルコマンドの多くが期待どおりに実行されないことに気付きました。
Rmが正しく実行できなかった後、dmesgからの出力から始めます。
プロセス6821(rm)からの長さ61440の割り当てに失敗しました
DMA 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 stable:0 free:821 slab:353 mapped:0 pagetables:0 bounce:0
DMAフリー:3284kB分:360kB低:448kB高:540kB active_anon:0kB inactive_anon:0kB active_file:4kB inactive_file:0kB unevictable:24kB present: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ページキャッシュページ
プロセスデータにRAM=を割り当てることができません。エラー番号12
最初は、連続したメモリの最大部分ではプログラムを実行できないと思いました。 DMA=は断片化しすぎていたので、システムにメモリを最適化させる方法を見つけなければなりませんでした。
次に、簡単な数学/健全性チェックを行ったところ、プログラムは64kBの連続したメモリスロットで実行できるはずでした。 Rmは61440バイト(60kB)を要求していました。
古き良き「手動デフラグ」を実行し、システムを再起動しました。システムを再起動すると、/ proc/buddyinfoが出力されます。
Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0
私はマップを疑っています:
しかし、上記の値のリストを合計すると、/ 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
要約すると、私の質問は:
私は、uClinuxバージョン2.6.30を実行するLantronixのXPort Pro(8MB、Linux OS)を使用しています。使用中のシェルは静かです。
少し時間がかかりましたが、3つすべてのサブ質問に対する回答ができるまで、回答を差し控えることにしました。
ただし、始める前に、「デフラグ」作業メモリに関して正しい用語が「コンパクト」作業メモリと呼ばれることを述べます。
私の結論は正しかった-隣接するRAMが不十分だったため、rmは実行されませんでした。システムはRAM=を取得し、それを断片化していたため、回収できませんでした。
組み込みシステムを再起動することを除いて、メモリを圧縮する方法はないことがわかりました。 MMUレスシステムの場合、防止はゲームの名前です。
LinuxカーネルをハッキングしてソフトウェアでMMUをエミュレートすることが可能かどうか、私の一部は考えています。可能であれば、誰かがすでにそれを行っていると思います。完全に想像することはできません。新しいコンセプト ;)
このプロジェクトでは、必要なたびにcronを使用してプログラムを手動で開始していました。これを行うはるかに良い方法は、起動時にプログラムを呼び出し、必要になるまでプログラムを強制的にスリープさせることです。この方法では、使用のたびにメモリを割り当てる必要はありません。したがって、断片化を減らします。
プロジェクトの最初の反復では、重要な機能(rmなど)を実行するために、シェルスクリプトの呼び出しに依存していました。必要がなければ、車輪を再発明する必要性はありませんでした。
ただし、MMUのないシステムでは、可能な限りシェルを使用しないことをお勧めします-
(質問、ls -la /path/to/directory/ | grep file-i-seek
を実行するとどうなりますか?)
(Answer:新しいサブプロセスを開始します)
Cプログラムにコアシェルスクリプト機能の一部を実装する必要がある場合は、 BusyBox で使用されているソースコードをチェックアウトすることをお勧めします。おそらく、組み込みシステムでCを使用することになるでしょう。
あなたの質問2(メモリの最適化)で、 https://www.kernel.org/doc/Documentation/sysctl/vm.txt から引用します:
compact_memory
CONFIG_COMPACTIONが設定されている場合にのみ使用できます。 1がファイルに書き込まれると、すべてのゾーンが圧縮され、可能な場合は連続したブロックで空きメモリが使用できるようになります。プロセスは必要に応じてメモリも直接圧縮しますが、これは、たとえば巨大なページの割り当てで重要になる場合があります。
これは、次のコマンド(root権限で実行され、上記のカーネルオプションが有効になっている場合)を意味します
echo 1 > /proc/sys/vm/compact_memory
カーネルにメモリをできるだけデフラグするように指示する必要があります。それに注意してください。一部のRHEL6バージョンでは、これによりカーネルがクラッシュする可能性があります...