RAMの最適化/ OOMの失敗


11

この質問はかなり長いので、最初に質問をしてから、質問にたどり着く方法を説明します。

  1. (Busyboxベースの)十分な連続したRAMがなかったため、rmは実行されませんでしたか?
  2. その場合、システムの再起動に頼らずにDMAをデフラグする軽量な方法はありますか?
  3. そうでない場合、何が原因ですか?どうすれば将来的にそれを防ぐことができますか?

この数日間、テストシステムがかなり集中的に実行されていた後、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を割り当てられません、errno 12

最初は、連続したメモリの最大部分でプログラムを実行することはできないと思いました。DMAが断片化しすぎていることを意味し、システムにメモリを最適化させる方法を見つける必要があります。

次に、簡単な数学/健全性チェックを行ったところ、プログラムは64kBの連続したメモリスロットで実行できるはずでした。Rmは61440バイト(60kB)を要求していました。

古き良き「手動デフラグ」を実行し、システムを再起動しました。システムを再起動すると、/ 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. 十分な連続RAMがなかったため、rmは実行されませんでしたか?
  2. その場合、システムの再起動に頼らずにDMAをデフラグする軽量な方法はありますか?
  3. そうでない場合、何が原因ですか?どうすれば将来的にそれを防ぐことができますか?

私は、uClinuxバージョン2.6.30を実行しているLantronixのXPort Pro(8MB、Linux OS)を使用しています。使用中のシェルは静けさです。


マイナーポイント:メモリチャンクのリストから1 x 2048 kBを除外しました。これを含めると、合計は3192 kBになり、/ proc / meminfoにリストされている3164 kBに非常に近くなります。
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 2014

7

少し時間がかかりましたが、3つすべてのサブ質問に対する回答ができるまで、回答を差し控えることにしました。

ただし、始める前に、「デフラグ」作業メモリに関して正しい用語が「コンパクト」作業メモリと呼ばれることを述べます。

1.十分な連続したRAMがなかったため、rmは実行されませんでしたか?

私の結論は正しかった-隣接するRAMが不十分だったため、rmは実行されませんでした。システムはRAMを取得して断片化していたため、回収できませんでした。

2.その場合、システムの再起動に頼らずにDMAをデフラグする軽量な方法はありますか?

組み込みシステムを再起動しない限り、メモリを圧縮する方法はないことがわかりました。MMUレスシステムの場合、防止はゲームの名前です。

ソフトウェアでMMUをエミュレートするためにLinuxカーネルをハッキングすることが可能かどうか、私の一部は考えています。私はそれが可能であるならば、誰かがすでにそれをしたと思います。私はそれがまったく新しいコンセプトだとは想像できません;)

3.どうすれば将来的にそれを防ぐことができますか?

このプロジェクトでは、必要なときにプログラムを手動で開始するためにcronを使用していました。これを行うはるかに良い方法は、起動時にプログラムを呼び出し、必要になるまでプログラムを強制的にスリープさせることです。この方法では、使用のたびにメモリを割り当てる必要はありません。したがって、断片化を減らします。

プロジェクトの最初の反復では、重要な機能(rmなど)を実行するために、シェルスクリプトの呼び出しに依存していました。必要がなければ、車輪を再発明する必要性はありませんでした。

ただし、MMUのないシステムでは、可能な限りシェルを使用しないことをお勧めします。

質問、実行するとどうなりますls -la /path/to/directory/ | grep file-i-seekか?)

回答:新しいサブプロセスを開始します)

Cプログラムにコアシェルスクリプト機能の一部を実装する必要がある場合は、BusyBoxで使用されているソースコードをチェックアウトすることをお勧めします。おそらく、組み込みシステムでCを使用することになるでしょう。


戻ってあなたの発見を共有してくれてありがとう。
カレブ2012

3
[これは古いことだと思います] MMUのエミュレーションは難しい... MMUがないと、すべてのプログラムがメモリバスにある物理アドレスを直接使用します。1つをエミュレートすることもできますが、実際のMMUが行うように、すべてのメモリアクセスをインターセプトする必要があります。パフォーマンスはひどいでしょう。または、間接ポインタを使用することもできますが(Mac OS Classicが「ハンドル」と呼ぶように)、完全に難しいAPIがあり、プリエンプションに直面すると非常に難しいAPIが使用されます(Mac OS Classicは協調マルチタスクを使用しました) 。
derobert 2013

戻ってきて、その応答を書く時間を割いてくれてありがとう。MacOSクラシックがそれをしたことを知りませんでした。
OldTinfoil 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.