Linux企業級開發技術(6)——libevent企業級開發之記憶體管理

尹成發表於2014-09-23


 

預設情況下,libevent使用C庫的記憶體管理函式在堆上分配記憶體。通過提供malloc、realloc和free的替代函式,可以讓libevent使用其他的記憶體管理器。希望libevent使

用一個更高效的分配器時;或者希望libevent使用一個工具分配器,以便檢查記憶體洩漏時,可能需要這樣做。

介面

void event_set_mem_functions(void*(*malloc_fn)(size_t sz),
void *(*realloc_fn)(void *ptr, size_tsz),
void (*free_fn)(void *ptr));


 

注意:

1、替換記憶體管理函式影響libevent隨後的所有分配、調整大小和釋放記憶體操作。所以,必須保證在呼叫任何其他libevent函式之前進行替換。否則,libevent可能用你的free函式釋放用C庫的malloc分配的記憶體。

2、你的malloc和realloc函式返回的記憶體塊應該具有和C庫返回的記憶體塊一樣的地址對齊。

3、你的realloc函式應該正確處理realloc(NULL,sz)(也就是當作malloc(sz)處理),realloc函式應該正確處理realloc(ptr,0)(也就是當作free(ptr)處理)

4、你的free函式不必處理free(NULL)

5、你的malloc函式不必處理malloc(0)

6、如果在多個執行緒中使用libevent,替代的記憶體管理函式需要是執行緒安全的。

7、libevent將使用這些函式分配返回給你的記憶體。所以,如果要釋放由libevent函式分配和返回的記憶體,而你已經替換malloc和realloc函式,那麼應該使用替代的free函

數。

 

這裡有個替換libevent分配器函式的示例,它可以計算已經分配的位元組數。實際應用中可能需要新增鎖,以避免執行在多個執行緒中時發生錯誤。

 

#include <event2/event.h>
#include <sys/types.h>
#include <stdlib.h>
 
union alignment {
   size_t sz;
   void *ptr;
   double dbl;
};
 
#define ALIGNMENT sizeof(union alignment)
 
#define OUTPTR(ptr)(((char*)ptr)+ALIGNMENT)
#define INPTR(ptr) (((char*)ptr)ALIGNMENT)
static size_t total_allocated = 0;
static void *replacement_malloc(size_t sz)
{
   void *chunk = malloc(sz + ALIGNMENT);
   if (!chunk)
             return chunk;
   total_allocated += sz;
   *(size_t*)chunk = sz;
   return OUTPTR(chunk);
}
static void *replacement_realloc(void *ptr,size_t sz)
{
   size_t old_size = 0;
   if (ptr) {
       ptr = INPTR(ptr);
       old_size = *(size_t*)ptr;
    }
   ptr = realloc(ptr, sz + ALIGNMENT);
   if (!ptr)
       return NULL;
   *(size_t*)ptr = sz;
   total_allocated = total_allocated old_
   size + sz;
   return OUTPTR(ptr);
}
static void replacement_free(void *ptr)
{
   ptr = INPTR(ptr);
   total_allocated = *(size_t*)ptr;
   free(ptr);
}
void start_counting_bytes(void)
{
   event_set_mem_functions(replacement_malloc,
   replacement_realloc,
    replacement_free);
}


 

相關文章