4

しばらくコーディングしていないので、前もって失礼します。私はこの奇妙な問題を抱えています。一度に 8GB を malloc しようとしていますが、後で TLSF でそのヒープを管理する予定です。つまり、アプリケーション全体で malloc することをまったく避けたいのです。最初に 1 つの大きなグロブを取得し、最後にそれを解放するだけです。しかし、ここに特異性があります。私は今までプログラムで常に dlmalloc を使用していました。それをリンクすると、すべてがうまくいきました。しかし、一度に 8GB を malloc しようとし、それを使用するために dlmalloc にリンクしようとすると、実行時に OSX でセグメンテーション エラー 11 が発生します。gcc を使用するか、clang を使用するかは問題ではありません。システムには8GBのRAMはありませんが、4GBあります。興味深いことに、32 GB の RAM を搭載した Windows マシンと 16 GB の RAM を搭載した Ubuntu マシンでも同じことが起こります。システムmallocを使用すると、すべて機能します。割り当てが行われ、割り当てられたメモリを介した単純な反復は、3 つのシステムすべてで期待どおりに機能します。しかし、dlmalloc でリンクすると失敗します。malloc と dlmalloc 関数呼び出しの両方で試しました。

割り当て自体は特別なことではなく、プレーンな c99 です。

[...]
size_t bytes = 1024LL*1024LL*1024LL*8LL;
unsigned long *m = (unsigned long*)malloc(bytes);
[...]

ここでいくつかのことで混乱しています。システムに4GBまたはRAMがなくても、システムmallocが8GBのmallocを提供するのはなぜですか?それらは仮想ページですか? dlmalloc が同じことをしないのはなぜですか? 割り当てる RAM の 8 GB の連続ブロックがない可能性があることは承知していますが、なぜセグメンテーション違反が発生し、null ptr ではないのでしょうか?

システムにそれほど多くのRAMがあるかどうかわからなくても、mallocからその量のRAMを一度に取得するための実行可能な堅牢な(できればプラットフォームニュートラルな)ソリューションはありますか?

編集:プログラムは、私が実行しているOSと同様に64ビットです。

edit2: それで、もう少し遊んでみました。割り当てを 1GB のチャンク、つまり 8 つの個別の malloc に分割すると、dlmalloc で動作することがわかります。したがって、連続したブロックがある場合にのみ dlmalloc がおそらく割り当てを試みる、連続した範囲の割り当てに関する問題のようです。これにより、私の質問が定式化するのがさらに難しくなります。プラットフォーム間で dlmalloc の有無にかかわらず、そのサイズのメモリ チャンクを取得し、物理メモリが残っていない場合に失敗しない方法はありますか (失敗しない限り、スワップすることができます)。また、クロスプラットフォームの方法で、malloc が RAM にあるかスワップにあるかを判断することもできます。

4

1 に答える 1

2

完全な答えではないにしても、私はあなたにほんの少しの視点を与えます. あなたが 8GB の連続した RAM を割り当てようとしているのを見ると、身がすくみます。はい、64 ビット コンピューティングなどでは、それはおそらく「合法」ですが、通常のマシンでは、おそらく多くのエッジ ケースに遭遇し、32 ビットのレガシー コードが 64 ビット サイズで窒息します。これを機能させるのに十分な大きさのメモリのチャンクを取得するという単純なユーザビリティの問題です。この種のことを試したい場合は、おそらくmalloc単一のチャンクを試してから、それが失敗した場合は、より小さなチャンクを使用してください。ただし、これは 1 チャンク システムの目的にやや反します。おそらくOSには、mallocサイズをリンクできるある種の「ページサイズ」があります-パフォーマンスを向上させ、必要な量のメモリを取得するための単純な機能です。

ゲーム コンソールでは、メモリ管理に対するこのアプローチはいくぶん一般的です。起動時に OS から 1 つのバッファをできるだけ大きく割り当ててから、独自のメモリ マネージャをそこに配置して、OS のオーバーヘッドと劣悪な割り当てコードの可能性を回避します。また、仮想メモリが存在しないようなシステムでメモリの断片化をより適切に制御することもできます。しかし、これらのシステムでは、搭載されている RAM の量も事前に正確に把握しています。

プラットフォームに依存しない方法でメモリが物理か仮想かを確認する方法はありますか? 私はそうは思いませんが、おそらく他の誰かがそれに良い答えを与えることができるので、この部分を編集します.

100% の答えではありませんが、役立ついくつかのランダムな考えと、複数のチャンクが正常に動作するように聞こえる場合に、1 つのチャンクで 8GB の RAM を必要とするあなたが何をしているのか、内部的に疑問に思っています。:)

于 2013-07-26T17:16:29.687 に答える