6

スレッドがバッファとして使用するために、それぞれ最大 100MB の大きなデータ セグメントをいくつか割り当てる必要があるマルチスレッド セクションがあります。さらに、実行時にバッファのサイズを数回変更する必要がある場合があります。

自然な解決策は使用するreallocことですが、必要のないメモリを移動する可能性があります。 free/mallocペアでバッファーのサイズを変更すると、フラグメンテーションが発生し、事前にメモリを予約すると、他の問題が発生する可能性があります。

メモリを割り当て/再割り当てするために、代わりに何を使用できますか?

4

3 に答える 3

5

とを使用freemallocます。これにより、断片化の問題が発生することはありません。

最新のアロケータは、メモリの断片化に対してかなり耐性があります。最近では、断片化の問題を引き起こすにはかなり病的なプログラムが必要です。プログラムが物理 RAM を直接アドレス指定した場合、断片化はより深刻な問題でしたが、仮想メモリを使用すると、プログラムのヒープに大きな「穴」があっても、リソースを消費する必要はありません。

さらに、バッファーのサイズが原因で、ほとんどのアロケーターは、バッファーごとにカーネルから専用の領域を要求します。Linux / OS X / BSD では、これは各バッファmmapの舞台裏での匿名を意味します。 これによりアドレス空間が断片化する可能性がありますが、仮想アドレス空間は基本的に 64 ビット システムではフリーであり、32 ビット システムでも数百メガバイトであれば問題ありません。

したがって、 と を使用freemallocます。

別の方法:各バッファーを必要以上に大きくした方が速い場合があります。この方法mallocは最新の Unix で機能し、書き込みを行わないページはメモリを消費しません。

したがってmalloc、500 MB のバッファーを使用して最初の 100 MB のみを使用する場合、プログラムは実際にはmalloc、100 MB のバッファーですべてを使用する場合よりも多くのメモリを使用しません。この方法ではアドレス空間の断片化が増えますが、64 ビット システムでは問題ありません。また、32 ビット システムでも機能するように、割り当てサイズをいつでも調整できます。

を使用する提案については、 / を /へのより単純なインターフェイスとmmap考えてください。これは、大規模な割り当ての場合です (1 MiB が一般的なしきい値です)。mallocfreemmapmunmap

于 2012-05-21T23:48:10.853 に答える
4

を使用するだけreallocです。最新のシステムでは、バッファが新しいアドレスに移動されたとしても、mremapデータをコピーするのではなく、ページテーブルを操作することによって移動が行われます (Linux では、他のシステムにも同様のメカニズムがあると確信しています)。(ここでは、大きなバッファーを想定していることに注意してください。通常は数百 kb 未満の小さなバッファーの場合、実際のコピーが行われます。)

ターゲットが 64 ビット マシンの場合、メモリの断片化について心配する必要はまったくありません。仮想アドレス空間が不足するほどメモリをひどく断片化することは決してありません。32 ビット マシンも処理する必要がある場合は、スレッドが多すぎない限り、おそらく安全です。合計メモリ消費量が1GB未満であれば、断片化による仮想アドレス空間の不足は非常に困難です。心配な場合は、必要になる可能性のある最大サイズを事前に割り当ててください。

于 2012-05-22T02:16:24.383 に答える
1

malloc/realloc/free を使用してソリューションを実装し、プロファイリングします。メモリ割り当てが問題になる場合は、facebook のjemallocや google のtcmallocなど、より優れた malloc の実装を使用できます。

2 つの比較については、 C++ メモリ割り当てメカニズムのパフォーマンス比較 (tcmalloc と jemalloc)を参照してください。

どちらも、内部/外部の断片化をうまく処理できます。

于 2012-05-21T23:41:18.520 に答える