2012-01-30 37 views
3

當您有一個動態分配的緩衝區,以不可預知的方式(例如向量或字符串)在運行時改變其大小時,優化其分配的一種方法是隻調整其後備存儲的權限2(或其他一組邊界/閾值),並保留未使用的額外空間。這有助於分攤搜索新的空閒內存和複製數據的成本,但會犧牲一點額外的內存使用量。例如,很多C++ stl容器的接口規範(reserve vs resize vs trim)都有這樣一個方案。malloc/realloc /可用容量優化

我的問題是Linux 3.0 x86_64,GLIBC 2.13,GCC 4.6(Ubuntu 11.10)上的malloc/realloc/free memory manager的默認實現是否有這樣的優化?

void* p = malloc(N); 
... // time passes, stuff happens 
void* q = realloc(p,M); 

換句話說,對於N和M(或在其他情況下)的哪些值,p == q?

回答

3

從glibc中樹幹的realloc的實施見在http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=12d2211b0d6603ac27840d6f629071d1c78586fe;hb=HEAD

首先,如果存儲器已經經由MMAP()獲得的,而不是SBRK(),它的glibc的malloc確實爲大的請求, > = 128 kB默認情況下,IIRC:


    if (chunk_is_mmapped(oldp)) 
    { 
    void* newmem; 

#if HAVE_MREMAP 
    newp = mremap_chunk(oldp, nb); 
    if(newp) return chunk2mem(newp); 
#endif 
    /* Note the extra SIZE_SZ overhead. */ 
    if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */ 
    /* Must alloc, copy, free. */ 
    newmem = public_mALLOc(bytes); 
    if (newmem == 0) return 0; /* propagate failure */ 
    MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); 
    munmap_chunk(oldp); 
    return newmem; 
    } 

(Linux有mremap(),所以實際上這是做了什麼)。

對於較小的請求,幾行字下面我們就

newp = _int_realloc(ar_ptr, oldp, oldsize, nb); 

其中_int_realloc是有點大,這裏複製粘貼,但你會發現它開始在上面的鏈接線4221。 AFAICS,它不執行常數因子優化增加,例如, C++ std :: vector的確如此,但恰好分配了用戶請求的數量(四捨五入到下一個塊邊界+對齊內容等等)。

我想這個想法是,如果用戶想要這個增加2倍的因素(或者任何其他常數因子增加以保證多次調整大小時的對數效率),那麼用戶可以自己在設施由C庫提供。