libevnet源码分析(2) --内存分配

xiaoxiao2021-03-01  17

写在前面:

​ 这个源码是分析libevent-2.0.20-stable, 并非最新版本的libevent,作者并没有全看源码,在这里会推荐以下参考的一些网站,也欢迎大家在不足的地方提出来进行讨论。

​ libevent源码分析

​ libevent深度剖析1

​ libevent深度剖析2

 

什么都没包装的内存管理

​ 默认情况下,libevent 使用 C 库的内存管理函数在堆上分配内存。通过提供 malloc、realloc和 free 的替代函数,可以让 libevent 使用其他的内存管理器。希望 libevent 使用一个更高效的分配器时;或者希望 libevent 使用一个工具分配器,以便检查内存泄漏时,可能需要这样做。

//mm-internal.h void *event_mm_malloc_(size_t sz); void *event_mm_calloc_(size_t count, size_t size); char *event_mm_strdup_(const char *s); void *event_mm_realloc_(void *p, size_t sz); void event_mm_free_(void *p); #define mm_malloc(sz) event_mm_malloc_(sz) #define mm_calloc(count, size) event_mm_calloc_((count), (size)) #define mm_strdup(s) event_mm_strdup_(s) #define mm_realloc(p, sz) event_mm_realloc_((p), (sz)) #define mm_free(p) event_mm_free_(p)

​ 当我们追溯这些文件,到event.c中,会看到这些所谓的函数,在没有自定义的情况下仅仅只是调用了C 的内存分配API

void * event_mm_malloc_(size_t sz) { if (_mm_malloc_fn) return _mm_malloc_fn(sz); else return malloc(sz); } void * event_mm_calloc_(size_t count, size_t size) { if (_mm_malloc_fn) { size_t sz = count * size; void *p = _mm_malloc_fn(sz); if (p) memset(p, 0, sz); return p; } else return calloc(count, size); } ​ void * event_mm_realloc_(void *ptr, size_t sz) { if (_mm_realloc_fn) return _mm_realloc_fn(ptr, sz); else return realloc(ptr, sz); } void event_mm_free_(void *ptr) { if (_mm_free_fn) _mm_free_fn(ptr); else free(ptr); }

尝试定义自己的内存管理函数

​ 看到上面的实现,一定会有人想问,上面的像_mm_free_fn到底是什么呢?我们要如何使用它呢?

static void *(*_mm_malloc_fn)(size_t sz) = NULL; static void *(*_mm_realloc_fn)(void *p, size_t sz) = NULL; static void (*_mm_free_fn)(void *p) = NULL;

​ 它们其实是event.c中的静态全局变量,所以我们仅只能通过下面的函数对其进行操作

void event_set_mem_functions(void *(*malloc_fn)(size_t sz), void *(*realloc_fn)(void *ptr, size_t sz), void (*free_fn)(void *ptr)) { _mm_malloc_fn = malloc_fn; _mm_realloc_fn = realloc_fn; _mm_free_fn = free_fn; }

​ 如果想编译生成的库含有上述宏和实现,就必须在编译定义_EVENT_DISABLE_MM_REPLACEMENT这个宏,这个宏的定义是靠./configure自动生成的event-config,h定义的,若想要取消自定义内存函数,可以在编Libevent

加入--disable-malloc-replacement。

 

不得不提的注意事项

替换内存管理函数影响 libevent 随后的所有分配、调整大小和释放内存操作。所以,必

须保证在调用任何其他 libevent 函数之前进行替换。否则,libevent 可能用你的 free 函数释放用 C 库的 malloc 分配的内存。

你的 malloc 和 realloc 函数返回的内存块应该具有和 C 库返回的内存块一样的地址对齐。

你的 realloc 函数应该正确处理 realloc(NULL,sz)(也就是当作 malloc(sz)处理)

你的 realloc 函数应该正确处理 realloc(ptr,0)(也就是当作 free(ptr)处理)

你的 free 函数不必处理 free(NULL)

你的 malloc 函数不必处理 malloc(0)

如果在多个线程中使用 libevent,替代的内存管理函数需要是线程安全的。

libevent 将使用这些函数分配返回给你的内存。所以,如果要释放由 libevent 函数分配和返回的内存,而你已经替换 malloc 和 realloc 函数,那么应该使用替代的 free 函数

其实这些条款看似复杂,其实就是一个两个问题:

​ 1.malloc realloc free要配套,否则加入你在自己申请的内存池分配空间,调用系统free,然后在下一次使用那块空间的时候,就会dump core

​ 2.在多线程的情况下要求线程安全

转载请注明原文地址: https://www.6miu.com/read-3200257.html

最新回复(0)