2012-09-25 63 views
4

首先減少的malloc調用,here是我得到了這個想法:通過分割一個大的malloc分配內存

曾經有一個應用程序,我寫了使用大量的內存 小斑點,每個分配與malloc()。它工作正常,但是緩慢。我只用一個替換了malloc的很多調用,然後 在我的應用程序中切分了大塊。速度要快得多。

我正在分析我的應用程序,當我減少了malloc調用的次數時,我得到了意想不到的性能提升。不過,我仍然在分配相同數量的內存。

所以,我想要做這個人做的,但我不確定最好的方法是什麼。

我的想法:

// static global variables 
static void * memoryForStruct1 = malloc(sizeof(Struct1) * 10000); 
int struct1Index = 0; 
... 
// somewhere, I need memory, fast: 
Struct1* data = memoryForStruct1[struct1Index++]; 
... 
// done with data: 
--struct1Index; 

陷阱:

  • 我必須確保我不超過10000
  • 我必須釋放內存以相同的順序我佔領了。 (在我的情況下不是主要問題,因爲我正在使用遞歸,但如果可能,我想避免它)。

從米哈伊Maruseac啓發:

首先,我創建的int鏈表,基本上告訴我這記憶指標都是免費的。然後我添加了一個屬性到我的結構叫int memoryIndex這幫助我返回任何順序佔用的內存。幸運的是,我確定我的內存需求在任何時候都不會超過5 MB,所以我可以安全地分配那麼多內存。解決了。

+1

這可能非常有用。如果您有一定的分配行爲可以利用,它可以節省時間和空間。例如,如果你知道你的內存使用情況是堆棧式的,或者你總是需要相同大小的數據塊。處理它的最好方法取決於這些要求。 –

回答

5

給你內存的系統調用是brk。通常的malloccalloc,realloc功能只是使用brk給出的空間。當這個空間不夠時,另一個brk被創建來創建新的空間。通常,虛擬內存頁面的大小會增加。因此,如果您確實想要預製對象池,請確保以頁面大小的倍數分配內存。例如,您可以創建一個4KB池。 8KB,...空間。

接下來的想法,看看你的對象。其中一些有一個大小,有些有其他大小。處理來自同一個池中的所有人的分配將是一件很痛苦的事情。爲各種大小的對象創建池(2的冪最好)並從它們中分配。例如,如果您有一個尺寸爲34B的對象,則可以從64B池中爲它分配空間。

最後,剩餘空間可以不用,也可以向下移動到其他池。在上例中,您有30B左側。你會將它分成16B,8B,4B2B塊,並將每個塊添加到它們各自的池中。

因此,你會使用鏈表來管理預分配的空間。這意味着你的應用程序會使用比實際需要更多的內存,但如果這對你真的有幫助,爲什麼不呢?

基本上,我所描述的是來自Linux內核的buddy allocatorslab allocator之間的混合。

編輯:在閱讀您的評論後,將很容易分配一個大面積malloc(BIG_SPACE)並將其用作記憶池。

+0

我真的很喜歡你的解釋,但我不知道如何使用它?我應該以某種方式通過'brk'分配一個大內存,那麼通過佔用這個空間,malloc調用會更快? – Mazyod

+0

順便說一句,我只有一個尺寸的對象。所以,它應該非常簡單。我想使用鏈接列表的想法,但我也無法確定。 – Mazyod

+0

不,'brk'只是爲了表明不是'malloc'花時間。做10KB的1KB的malloc與3KB的4KB的malloc相同。 –