今日は一連のプログラムのストレステストをしています。プログラムの入力負荷を大幅に増やし、最初は動作しましたが、メモリを吸い込む顕著なメモリリークが発生しました。唯一の問題は、1)Valgrind
漏れがなく、2)パケット収集速度が高い場合にのみ発生することです。
おそらくクレイジーなアイデアの1つは、私のシステムがパケットが入ってくる速度でパケットを出力する帯域幅が不足しているため、追加のメモリがメッセージキューに移動して、より大きなデータバッファを送信できるようにすることです。メモリを大量に消費するプログラムがTCPソケットからデータを読み取り、名前付きパイプに書き込んでいることを示します。だから、3つの質問があります。
TCP / IPまたは名前付きパイプの場合、ディスパッチするデータを格納するために使用されるメモリキューは無限に大きくなる可能性がありますか?
キューが大きくなったり大きくなったりすると、まだ私のプログラム(TCPから読み取られ、名前付きパイプに出力されるプログラム)がメモリを大量に占めるようにマークされますか、それともメモリがシステムメモリとして表示されますか?
これらのキューに割り当てられているメモリを確認するために使用できるコマンドはありますか?セントースを書いています。
もちろん、それが私が流出した理由ではないと思いますが、別のものが何なのか推測できなかったので尋ねるしかありませんでした!
ベストアンサー1
- 一般的に言えば、非常に限られています。が二つ(少なくとも)これらのバッファが存在できる場所は次のとおりです。
- カーネルから。確かに境界があります。私はFIFOがハードコーディングされており、/を
/proc/sys/kernel/tcp_wmem
使用してTCPを(およびrmem)および(proc制限内で)設定できると思います。詳細については、tcp(7) マンページを参照してください。setsockopt
SO_SNDBUF
SO_RCVBUF
- あなたのアプリケーションに。 writeなどを直接呼び出さないと、使用しているライブラリに独自のバッファがある可能性があります。これら可能無制限です。
- さて、実際には3番目の場所はネットワークカードのRAMです。はんだ付けせずに特定(かなり小さい)限度以上に増やす方法がないので無視しました。ああ、ネットワークカードのDMA用転送リングバッファもあります。繰り返しますが、固定サイズ(ethtoolは可能であれば調整されます)です。
- カーネルから。確かに境界があります。私はFIFOがハードコーディングされており、/を
- カーネルはシステムメモリとして表示されます。アプリケーション内のアイテムは、アプリケーションの仮想サイズ(および常駐サイズなど)の一部として表示されます。
netstat -t
各 TCP 接続の送受信キューの現在のサイズが表示されます。ライブラリに保存されているコンテンツについては、該当する文書を確認してください。
覚えておいてください、覚えていません。方法を提供いよいよ解いてみると。アプリケーションのキューの増加が困難になっている場合、これは景品ではありません。メモリ断片化の増加に苦しんでいる場合も同様です。