0

独自の物理メモリを管理する独自の my_malloc() 関数を作成しました。私のアプリケーションでは、libc の malloc() と独自の my_malloc() 関数の両方を使用できるようにしたいと考えています。したがって、どうにかして仮想アドレス空間を分割する必要があります。malloc は、専用プールからの場合にのみ常に仮想アドレスを割り当てる必要があります。my_malloc() と同じです。ヒープ サイズを制限することはできません。malloc() と my_malloc() が同じ/重複する仮想アドレスを返さないことを保証する必要があるだけです。

ありがとう!

4

4 に答える 4

1

仮想アドレス空間の大きなブロックを予約し、それをmy_malloc()割り当て元のプールにします。OS から大量の連続したメモリ領域を予約すると、その後の呼び出しはmalloc()別の場所から行う必要があります。

たとえば、Windows では、 VirtualAlloc()を使用して 256 MB のスペース ブロックを予約できます。メモリは、後続の呼び出しで「コミット」するまで実際には割り当てられませんが、その後malloc()使用されないアドレス範囲 (0x4000000-0x5000000 など) が予約されます。次に、my_malloc()要求に応じてこの予約された範囲からブロックをコミットし、作成した割り当てスキームによってそれらを細分化することができます。

同等の Linux 呼び出しは mmap()だと言われています。(編集:以前、「メモリを物理的に連続させる必要があるかどうかに応じて、kmalloc またはvmalloc 」と言いましたが、これらはカーネルレベルの関数です。)

アプリでこのメカニズムを使用して、特定のサイズのすべての割り当てを独自のカスタム プール ブロック アロケーターにリダイレクトし、速度と効率を高めています。とりわけ、CPUがより効率的に処理できる特定のサイズの仮想ページを予約できます。

于 2012-05-04T22:36:23.007 に答える
1

1 つの答えは、my_mallocによって割り当てられたメモリを使用することmallocです。十分な大きさのブロックを使用すると、ほとんどの場合それが達成されます。次に、各ブロック内でバージョンが独自の構造を維持し、その一部を呼び出し元に割り当てます。

メモリを取得するときのように、バージョンで使用可能なスペース全体を拡張することに依存できないため、注意が必要ですsbrk。したがって、バージョンはいくつかのブロックを維持する必要があります。

于 2012-05-04T22:27:10.630 に答える
1

可能性の 1 つは、起動時にmy_malloc()呼び出しmalloc()て大きなメモリ プールを事前に割り当て、そのメモリを呼び出し元に割り当て、それに応じて管理することです。ただし、完全な実装では、ガベージ コレクションと最適化を処理する必要があります。

別の可能性は、メモリを割り当てる必要があるたびにmy_malloc()呼び出し、割り当てられたブロックの数、解放されたブロックの数、未処理の最大ブロック、割り当てられたメモリの合計などmalloc()、関心のある「簿記」の側面を処理することです。すべての「難しい」操作を に渡すため、これははるかに安全で効率的なメカニズムです。malloc()

于 2012-05-04T22:28:36.547 に答える
0

プログラムの開始近くに呼び出しを追加するmmap(2)と、必要なアドレスに必要なだけのメモリをすぐに割り当てることができます (ヒントNULLを参照してください。通常、OS が決定するために残されます)。malloc(3)、または他のメモリ割り当てルーチンがそれらの特定のページを取得するのを防ぎます。

メモリ使用量について心配する必要はありません。最新のシステムはオーバーコミットを非常に喜んで行うため、ページ テーブルを処理するために使用するカーネル スペースは数百キロバイト増えるだけです。悪くない。

于 2012-05-04T22:28:50.280 に答える