3

多数の CORBA サーバー プロセスを実行する Linux システム (kubuntu 7.10) があります。サーバー ソフトウェアは、メモリ割り当てに glibc ライブラリを使用します。Linux PC には 4G の物理メモリがあります。速度上の理由から、スワップは無効になっています。

データを処理する要求を受信すると、サーバー プロセスの 1 つが大きなデータ バッファーを割り当てます (標準の C++ 演算子 'new' を使用)。バッファ サイズはパラメータの数によって異なりますが、通常は約 1.2G バイトです。約 1.9G バイトまで可能です。リクエストが完了すると、「delete」を使用してバッファが解放されます。

これは、同じサイズのバッファを割り当てる複数の連続するリクエストに対して、またはリクエストが以前よりも小さいサイズを割り当てる場合にうまく機能します。メモリは問題なく解放されているように見えます。そうしないと、数回のリクエストの後、最終的にバッファ割り当ての試行が失敗します。いずれにせよ、KSysGuard などのツールを使用して、リクエストごとにバッファ メモリが割り当てられ、解放されていることがわかります。

この問題は、リクエストが以前よりも大きなバッファを必要とする場合に発生します。この場合、演算子 'new' は例外をスローします。最初の割り当てから解放されたメモリは、使用可能な空き物理メモリが十分にあるにもかかわらず、再割り当てできないかのようです。

最初の操作の後にサーバー プロセスを強制終了して再起動すると、より大きなバッファー サイズに対する 2 番目の要求が成功します。つまり、プロセスを強制終了すると、解放されたメモリがシステムに完全に解放されるように見えます。

ここで何が起こっているのかについて、誰かが説明できますか? ある種の断片化またはマッピング テーブル サイズの問題でしょうか? new/delete を malloc/free に置き換え、malopt を使用してメモリがシステムに解放される方法を調整することを考えています。

ところで-それが私たちの問題に関連しているかどうかはわかりませんが、サーバーは、処理要求ごとに作成および破棄される Pthreads を使用します。

4

3 に答える 3

4

これが 32 ビット マシンの場合、3Gb のアドレス空間を自由に使用できます。1Gb はカーネル用に予約されています。そのうち、かなりのアドレス空間が共有ライブラリ、exe ファイル、データ セグメントなどによって使用されます。 ./proc/pid/mapsアドレス空間がどのように配置されているかを確認するには、 を参照してください。

利用可能な物理アドレス空間の量を知るのは難しく、すべてのシステムプロセス、カーネル、およびその他のプロセスがそれを食い尽くします。これらの合計が 1Gb を超えないと仮定すると、まだ 3Gb を使用できます。

起こっている可能性があるのは、断片化です。

0Gb 3Gb
----------------------~-------------------------------- --------
|もの | ヒープ、1.2Gb 割り当て済みのもの | 空きヒープ | スタック|
----------------------~-------------------------------- --------

次に、大きなオブジェクトを解放しますが、その間に他のメモリが割り当てられているため、次のようになります。

0Gb 3Gb
----------------------~-------------------------------- --------------
|もの | ヒープ、1.2Gb 空き |小さなオブジェクト | 空きヒープ | スタック|
----------------------~-------------------------------- --------------

今より大きなオブジェクトを割り当てようとすると、空き 1.2Gb スペースに収まりませfree heapん。十分なスペースがない可能性があるため、スペースにも収まらない可能性があります。

スタックを頻繁に使用している場合、スタックが成長してスペースを消費している可能性がありますが、それ以外の場合はヒープスペースに使用できますが、ほとんどのディストリビューションはデフォルトでスタックを 8 ~ 10Mb に制限しています。

malloc/realloc を使用しても、これは役に立ちません。ただし、必要な最大オブジェクトのサイズがわかっている場合は、起動時にそのサイズを確保できます。その部分は解放/削除してはならず、再利用する必要があります。他の場所で別の問題が発生するかどうかはわかりませんが、他のオブジェクトに使用できるスペースが少なくなります。

于 2010-03-29T19:08:52.783 に答える
0

アドレス空間が不足しているため、割り当てを満たすのに十分な大きさの単一のチャンクがありません。

解決策は、64 ビット オペレーティング システムを実行することです。結局のところ、今は 21 世紀です!

もちろん、アプリケーションの 64 ビット互換性を再テスト (および再コンパイルなど) する必要がありますが、長期的には意味があります。最近のサーバーにとって、4G は大容量の RAM ではありません。かなり控えめなものは16-32Gです。

于 2010-03-30T15:48:48.223 に答える
0

返信ありがとうございます。さらに調査すると、断片化が実際に問題であることがわかります。最初のリクエストが到着したときに必要になる最大のバッファを予約し、後続のリクエストのためにそのバッファを保持することは機能しているようです。

于 2010-03-30T13:52:40.413 に答える