Libevent源码分析-----内存分配
来源:互联网 发布:关于网络推广的方法 编辑:程序博客网 时间:2024/05/22 14:37
Libevent的内存分配函数还是比较简单的,并没有定义内存池之类的东西。如同前一篇博客那样,给予Libevent库的使用者充分的设置权(定制),即可以设置用户(Libevent库的使用者)自己的内存分配函数。至于怎么分配,主动权在于用户。但在设置(定制)的时候要注意一些地方,下面会说到。
首先,如果要定制自己的内存分配函数,就得在一开始配置编译Libevent库是,不能加入--disable-malloc-replacement选项。默认情况下,是没有这个选项的。如果加入了这个选项,那么将会在生成的event-config.h中,定义_EVENT_DISABLE_MM_REPLACEMENT这个宏。关于event-config.h文件,可以参考博文。下面是Libevent内存分配函数的声明(在mm-internal.h文件):
- //mm-internal.h文件
- #ifndef _EVENT_DISABLE_MM_REPLACEMENT
- 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)
- #else
- #define mm_malloc(sz) malloc(sz)
- #define mm_calloc(n, sz) calloc((n), (sz))
- #define mm_strdup(s) strdup(s)
- #define mm_realloc(p, sz) realloc((p), (sz))
- #define mm_free(p) free(p)
- #endif
这些内存分配函数是给Libevent使用的,而非用户(从这些接口声明在mm-internal.h文件中就可以看到这一点)。Libevent的其他函数要申请内存就调用mm_malloc之类的宏定义。如果一开始在配置的时候(event-config.h)就禁止用户定制自己的内存分配函数,那么就把这些宏定义为C语言标准内存分配函数。
当然,即使没有禁止,如果用户没有定制自己的内存分配函数,最终还是调用C语言的标准内存分配函数。这一点在event_mm_xxxx这些函数的实现上可以看到。
这些函数的实现是在event.c文件中的。定制功能的实现原理和前一篇博客中说到的定制实现原理是一样的。如下:
- #ifndef _EVENT_DISABLE_MM_REPLACEMENT
- 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;
- 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_mm_malloc_
- void *
- event_mm_malloc_(size_t sz)
- {
- if (_mm_malloc_fn)
- return _mm_malloc_fn(sz);
- else
- return malloc(sz);
- }
如果用户定制了内存分配函数(_mm_malloc_fn不为NULL),那么就直接调用用户定制的内存分配函数。否则使用C语言标准库提供的。其他几个内存分配函数也是这样实现的。这里就不贴代码了。
定制自己的内存分配函数需要注意的一些地方:
- 替换内存管理函数影响libevent 随后的所有分配、调整大小和释放内存操作。所以必须保证在调用任何其他libevent函数之前进行定制。否则,Libevent可能用定制的free函数释放C语言 库的malloc函数分配的内存
- malloc和realloc函数返回的内存块应该具有和C库返回的内存块一样的地址对齐
- realloc函数应该正确处理realloc(NULL, sz)(也就是当作malloc(sz)处理)
- realloc函数应该正确处理realloc(ptr, 0)(也就是当作free(ptr)处理)
- 如果在多个线程中使用libevent,替代的内存管理函数需要是线程安全的
- 如果要释放由Libevent函数分配的内存,并且已经定制了malloc和realloc函数,那么就应该使用定制的free函数释放。否则将会C语言标准库的free函数释放定制内存分配函数分配的内存,这将发生错误。所以三者要么全部不定制,要么全部定制。
参考:
http://www.wangafu.net/~nickm/libevent-book/Ref1_libsetup.html- Libevent源码分析-----内存分配
- Libevent源码分析-----内存分配
- Libevent源码分析-----内存分配
- Libevent源码分析-----内存分配
- Libevent源码分析-----内存分配
- Redis源码分析-内存分配
- Redis源码分析-内存分配
- Redis源码分析-内存分配
- Box2D源码分析:栈内存分配B2StackAllocator
- 【redis源码分析】内存分配---zmalloc
- python源码分析----内存分配(1)
- python源码分析----内存分配(2)
- 源码分析:Java对象的内存分配
- 源码分析:Java对象的内存分配
- 【golang 源码分析】内存分配与管理
- Libevent-2.1.8源码分析——内存管理
- libevent源码分析
- libevent源码分析
- 数组长度为零和空引用的区别 files!=null&files.length()>0 空指针或赋空值
- N!
- ZigBee3.0_JENNIC-JN516x-ZigBeeBaseDevice_20170606_1.2
- 459. Repeated Substring Pattern
- Java — 面向对象的三大特性(封装、继承、多态)
- Libevent源码分析-----内存分配
- leetcode 226. Invert Binary Tree
- InfiniBand技术和协议架构分析
- Python廖雪峰实战web开发(day4-编写Model)
- udp采用sendmsg发送消息失败
- 地球上有外星人?真的?还是假的?
- Java学习笔记 --- Java中常用的包及其重要的类简要概括
- 谈谈进程间通信的几种方式?
- Libevent源码分析-----多线程、锁、条件变量(一)