2016-10-07 28 views
0

プロセスがmallocを呼び出すときにI/O(キャッシュの交換など)が行われてメモリが利用可能になると仮定するのは間違いですが、これはかなりの時間をブロックする可能性があることを意味します。したがって、私たちはlinuxに2つのバージョンのmallocを持つべきではありません.1つは、小さなチャンクを得るのに適した "fast_malloc"と言います。&はブロックされないことが保証されています(もちろんOUT_OF_MEMORYで失敗するかもしれません)。スペースは必要ですが、コールバックが必要ですか?mallocは非同期ではありませんか?

例:リンクリスト内の項目の空き領域を確保するために必要なメモリ容量が小さい場合は、従来のインラインmallocよりOSが99.999%の時間を満たしているか、 。もう1つの例:インデックスに入れられるかなりのチャンクを割り当てようとしているDBサーバーの場合、私はasync_mallocを選択して "コールバックの複雑さ"を扱うかもしれません。

私がこれを持ち出した理由は、毎秒何十万というWeb要求を処理する非常に並行したサーバーを作成し、一般的に要求を処理するためのスレッドを避けることです。別の言い方をすれば、I/Oが発生するたびに、それを非同期にしたい(libeventベース)。残念ながら私は、ほとんどのC APIが同時使用のための適切なサポートが不足していることを認識しています。たとえば、ユビキタスなMySQL Cライブラリは完全にブロックされており、それは私のサーバが広範囲に使用するライブラリの1つです。繰り返しますが、私はいつも他のスレッドにオフロードすることでノンブロッキングをシミュレートできますが、完了コールバックで結果を待つほど安くはありません。 kaylumとして

+5

'malloc'を呼び出すことは、本質的により多くのIOを引き起こすことはありません。たぶんあなたは、あなたにメモリを割り当てるだけではなく、返されたメモリを混乱させているかもしれません。あなたが100MBを求めるのは、mallocが直ちに100MBのスワップを引き起こすわけではありません。それはメモリにアクセスするときにのみ起こります。 – kaylum

+0

Cは 'malloc()'のタイミング性能を指定していません。確かに、これはタイミングの問題がある最初のアプリケーションではありません。主要なOSである典型的な 'malloc()'は、長い時間ブロッキングを避け、代わりに使用時にしか割り当てません。 http://stackoverflow.com/q/19991623/2410359。 – chux

答えて

3

はコメントで述べている:mallocを呼び出す

は、本質的にIOが発生することはありません。たぶんあなたは、あなたにメモリを割り当てるだけではなく、返されたメモリを混乱させているかもしれません。ちょうどあなたが100MBを求めるのであれば、mallocは直ちに100MBのスワップを引き起こすという意味ではありません。それはあなたがメモリにアクセスするときにのみ起こります。

あなたが割り当てられたメモリへ以降のアクセスの間など、スワップのための長い遅延から保護したい場合は、別のスレッド(そう、あなたのプロセスが停止されていない待機中でmlockを呼び出すことができますmlockが完了するまで)。 mlockが成功すると、メモリは物理的にインスタンス化され、munlockまでスワップアウトできません。

2

malloc()を呼び出しても、必ずしもプログラムがOSにメモリを要求するとは限りません。これは、Cランタイムのmalloc()の実装にまで及んでいません。

glibc malloc()の場合、単にあなたが求めているものによっては、ランタイムが既にOSから取得したメモリへのポインタを返します。同様に、free()は必ずしもメモリをOSに返すわけではありません。そんなに速いです。私はglibcのmalloc()もスレッドセーフであると思います。

興味深いことに、C、C++(上に構築されたものすべて)には、通常JavaやC#などの言語に関連付けられているのと同じ種類のプロパティがあります。 glibcのようなランタイムの上にJavaやC#のようなランタイムを構築することは、malloc()や全く新しいものを使用していない限り、実際にはメモリを管理する上で必要以上に多くの作業があることを意味します。

そこにはさまざまなアロケータがあり、通常のCランタイムが提供しているものとは無関係に、あなたが望むものにリンクすることができます。だから、* BSDのようなプラットフォームでも(通常、メモリ割り当てのアプローチではずっと伝統的ですが、malloc()や新しいものを呼び出すたびにOSに尋ねます)、同じトリックを引き出すことができます。

+0

*私はglibcのmalloc()もスレッドセーフであると思います。*そうです。実際、glibcの 'malloc'実装は、スレッドごとにスレッドローカル(プライベート)アリーナを管理します。したがって、' malloc'を同時に呼び出す複数のスレッドが同時に衝突することはほとんどありません。 –

1

I/Oが発生するたびに、私は非同期(libeventベース)としたいと思います。

私はあなたに悪い知らせがあります。メモリにアクセスするたびに、I/Oのブロックが発生します。

mallocシステムコールは、カーネルに「アクセス時にここにマップする」というデータ構造体にエントリを作成するだけなので、ブロックすることはほとんどありません。つまり、mallocは、より多くのメモリをマップするためにカーネルに移動する必要があるときだけブロックし、カーネルのメモリが不足しているため、内部データ構造の割り当てを待たなければなりません(かなり長い間待つことができます)またはmlockallを使用します。スワッピングを引き起こすメモリの実際の割り当ては、メモリに触れるまで行われません。そしてあなた自身の記憶はいつでも(またはあなたのプログラムのテキストがページアウトされるかもしれない)スワップアウトされ、あなたはそれをほとんど制御できません。

関連する問題