1

VirtualAllocを使用して仮想メモリを予約できることはわかっています。
たとえば、1 GBの仮想メモリを要求し、その最初のMBを呼び出して、増大するアレイを配置できます。
配列が1MBを超えると、2番目のMBを呼び出します。
このように、アレイが大きくなったときにアレイをメモリ内で移動する必要はありません。アレイはそのまま残り、Intel/AMD仮想メモリマネージャが問題を処理します。

ただし、FastMMはこの構造をサポートしているので、独自のメモリ管理を行う必要はありませんか?

擬似コード:

type
  PBigarray = ^TBigarray;
  TBigArray = array[0..0] of SomeRecord;

....

begin
  VirtualMem:= FastMM.ReserveVirtualMemory(1GB);
  PBigArray:= FastMM.ClaimPhysicalMemory(VirtualMem, 1MB);
....

procedure GrowBigArray
begin
  FastMM.ClaimMorePhysicalMemory(PBigArray, 1MB {extra});
  //will generate OOM exception when claim exceeds 1GB

FastMMはこれをサポートしていますか?

4

1 に答える 1

3

いいえ、FastMM4(私が調べた最新バージョンの時点)はこれを明示的にサポートしていません。VirtualAlloc呼び出しを使用すると簡単に実行できるため、汎用メモリマネージャーに期待される機能ではありません。

NexusMM4(NexusDBの一部)は、同様の結果をもたらす何かを実行しますが、バックグラウンドで必要になる前にすべてのアドレス空間を無駄にすることはありません。

最初に大規模な割り当てを行う場合(GetMemを介して直接、または動的配列などを介して間接的に)、VirtualAllocを介して、必要なサイズだけでメモリが割り当てられます。

ただし、その割り当てのサイズがより大きなサイズに変更された場合、NexusMMは別の方法を使用してメモリを割り当てます。これにより、アドレススペースから割り当てを単純にマップ解除し、さらに再割り当てが行われたときに、より大きなサイズで再度マップします。

これにより、ほとんどの汎用メモリマネージャが再割り当て時に発生する2つの主要な問題が回避されます。

  • 通常の再割り当て中に、既存の割り当てと新しい割り当てが同時にアドレススペースに存在する必要があり、アドレススペースと物理メモリの要件が一時的に2倍になります。
  • 通常の再割り当て中に、既存の割り当ての内容全体をコピーする必要があります

したがって、NexusMMを使用すると、通常のGetMem / ReallocMem / FreeMem呼び出しを使用するだけで、疑似コードに示したすべての利点を得ることができます(ただし、最初のreallocにはコピーが含まれ、配列を大きくするとアドレスが変更される可能性があります)。 。

于 2011-06-17T13:53:28.100 に答える