2011-06-17 57 views
1

我知道我可以使用VirtualAlloc保留虛擬內存。
例如我可以聲稱1GB的虛擬內存,然後調用第一個MB來放入一個增長的數組。
當數組增長超過1MB時,我在第二個MB中調用,等等。
這種方式我不需要在內存中移動陣列,它只是保持原樣,Intel/AMD虛擬內存管理器會照顧我的問題。FastMM是否支持保留虛擬內存和調用塊來增長數組?

但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支持呢?

+3

這有一個[XY問題]的特點(http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。我在猜測你真正的問題是什麼,但我懷疑你正在遭受地址空間碎片化,因爲你的代碼需要大量連續的內存塊。如果是這樣的話,最好的解決方案是分配非連續的塊,然後*將它們拼接在一起*在幕後,這樣這些較小的塊看起來像是連續的塊。 – 2011-06-17 11:53:42

回答

3

不,FastMM4(截至我看到的最新版本)沒有明確支持這一點。這實際上不是您在通用內存管理器中所期望的功能,因爲使用VirtualAlloc調用非常簡單。

NexusMM4(它是NexusDB的一部分)可以爲您提供類似的結果,但不會在後臺需要之前浪費所有地址空間。

如果您進行初始大分配(直接通過GetMem,或通過動態數組或類似方式間接),通過VirtualAlloc將內存分配爲所需的大小。

但是,如果該分配隨後調整爲較大的大小,則NexusMM將使用不同的方式分配內存,從而允許它簡單地從地址空間取消映射分配,並以更大的大小再次重新映射,發生。

這可以防止大多數通用的內存管理器重新分配時,有兩個主要的問題:正常的realloc現有的和新的分配需要出現在地址空間,同時在

  • ,臨時增加一倍地址空間和物理內存要求
  • 正常的realloc期間
  • ,需要被複制

現有分配的全部內容,因此,與NexusMM,你會得到一個什麼樣的所有優點您只需使用普通的GetMem/ReallocMem/FreeMem調用,就可以在您的僞代碼中展示(除了第一個realloc將涉及副本,並且增加數組可能會更改其地址)。