バイト配列でスペース(動的サイズ)を割り当て、「スペースエリア」へのポインターを取得し、不要になった場合は後で解放したいと思います。
VirtualAlloc、VirutalAllocEx、LocalAllocについて知っています。どれが最適で、後でメモリを解放するにはどうすればよいですか?
ご協力ありがとうございました。
バイト配列でスペース(動的サイズ)を割り当て、「スペースエリア」へのポインターを取得し、不要になった場合は後で解放したいと思います。
VirtualAlloc、VirutalAllocEx、LocalAllocについて知っています。どれが最適で、後でメモリを解放するにはどうすればよいですか?
ご協力ありがとうございました。
ネイティブのPascal関数の代わりにwinapiを使用するのは良い考えではないと思います。
バイトの配列を次のように定義するだけです。
var yourarray: array of byte;
その後、それを割り当てることができます
setlength(yourarray, yoursize);
によって解放されます
setlength(yourarray, 0);
このような配列は参照カウントされ、次のように個々のバイトにアクセスできます。yourarray[byteid]
または、本当にポインタが必要な場合は、次を使用できます。
var p: pointer;
GetMem(p, yoursize);
FreeMem(p);
GetMem/FreeMem
または動的配列、またはを使用することをお勧めしますRawByteString
。GetMem/FreeMem
動的配列またはヒープRawByteString
を使用し、その割り当てにはスタックを使用しないことに注意してください。
VirtualAlloc/VirtualFree
の代わりに使用することに関心はありませんGetMem/FreeMem
。大きなブロックの場合、(ヒープを実装する)メモリマネージャーはVirtualAlloc/VirtualFree
APIを呼び出しますが、小さなブロックの場合は、ヒープに依存するように最適化されます。
は現在のプロセスに対してローカルであるため、これVirtualAlloc/VirtualFree
を使用する唯一の関心事は、コードを実行できるメモリブロックを作成する場合です。たとえば、VirtualAllocEx/VirtualFreeEx
APIを介してクラスまたはインターフェイスのスタブラッパーを作成する場合です(ただし、それが必要かどうかはわかりません)。 )。
すべてのプロセス/プログラムに対してグローバルなメモリを使用する場合は、GlobalAlloc/GlobalFree
API呼び出しが手元にあります。
VirtualAllocはページ割り当て関数です。これは、メモリを割り当てるための低レベルのユーザースペースコード関数です。ただし、VirtualAllocから返されるメモリは、ページサイズの倍数に揃えられていることを理解する必要があります。
Windows 32ビットでは、ページサイズは通常4096バイトです。他のシステムでは、それが大きくなる可能性があります。
したがって、これにより、ページ全体のメモリが必要な場合にVirtualAllocが役立ちます。VirtualAllocは、大きな「ページの範囲」を割り当てることができます。ページは仮想であるため、実際には基盤となるシステムRAMにマッピングされ、半分の時間がスワップファイルにスワップアウトされます。これが、仮想に重点を置いたVirtualAllocと呼ばれる理由です。
VirtualAllocとVirtualAllocExを使用すると、メモリの一部のページを予約することもできます。予約済みページは、使用されることが確実になるまで予約済み状態に保持される範囲です。使用されると、ページをコミットできます。その時点で、ページに必要な基になるリソースが割り当て/コミットされます。
VirtualFreeを使用して、VirtualAllocで割り当てまたは予約したページを解放します。
VirtualAllocとLocalAllocの違いは、LocalAllocがヒープから割り当てることと、ヒープは、予約されたページのはるかに大きなブロックからメモリのブロックを割り当てるメカニズムであるということです。内部的には、ヒープはVirtualAllocを使用してメモリの大きなセクションを割り当て、それらのページを小さなブロックに分割します。これらのブロックは、malloc、getmem、LocalAllocなどの関数から返されるバッファーとして表示されます。
LocalAllocは、Windowsに組み込まれているバージョンのmallocまたはgetmemと考えることができます。LocalAllocの呼び出しは、C ++でのmallocの呼び出し、またはDelphiでのgetmemの呼び出しに似ています。実際、DelphiでGetMemをオーバーライドして、LocalAllocを使用すると、DElphiアプリケーションはおそらく同じように実行されます。
LocalFreeを呼び出して、LocalAllocで割り当てられたメモリを解放します。内部的には、これはメモリのブロックを次の呼び出し元が使用できるものとしてマークします。
したがって、決定する際の現在の主な考慮事項はオーバーヘッドです。頻繁に割り当てる必要がある場合は、LocalAllocまたはgetmemを使用する必要があります。これは、仮想ページのコミットと予約がより時間のかかるプロセスであるためです。
つまり、特別な理由がない限り、getmemまたはLocalAllocを使用してください。
Delphi5とC++コンパイラを使用したすべてのテストで、Delphi 5のgetmemの方が高速でしたが、それは5年前のことです。それ以来、より速いかもしれない貯蔵のようなアロケータが利用可能です。しかし、変数が非常に多い場合、何が速いかを言うのは難しいです。
ただし、LocalAlloc、malloc、getmemなどのすべてのヒープ関数は、LocalAllocやgetmemなどのヒープ関数用に内部でメモリを予約するために通常使用されるVirtualAllocを使用して割り当て、解放するよりもはるかに高速である必要があります。
Pascalプログラムの場合、移植性が高いため、getmemまたはSetLengthをお勧めします。または、独自のラッパー関数をLocalAllocまたはOSヒープ関数に書き込むことができます。
リストした関数は、プラットフォームに依存するWinAPI関数です。明らかに、割り当てに使用したものと同じAPIの関数を使用して割り当てを解除する必要があります。
Delphiメモリマネージャを使用する場合は、GetMemoryとFreeMemoryよりも当然の選択ですが、ポインタをシステムページサイズ(一部の低レベルライブラリの要件)に合わせる必要がある場合、または大きなバッファを使用する場合サイズ、そしてWindowsAPI仮想メモリ関数VirtualAllocとVirtualFreeはあなたの親友です。