• Linux企业级开发技术(6)——libevent企业级开发之内存管理



    默认情况下,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);
    }


  • 相关阅读:
    J2SE-反射
    c3p0 连接数据库失败的问题
    c# 调用存储过程
    存储过程使用truncate时
    Parcelable intent传递对象时,需要将该对象实现Parcelable 或者Serializable
    android intent 在打开设置activity的时候在监听事件的内部 适用setclass()方法时 不是直接适用this 关键字
    c# 读取appconfig文件
    Oracle 连接数据库的几种方式
    通过反射获得方法,和绑定事件
    js 验证
  • 原文地址:https://www.cnblogs.com/new0801/p/6176897.html
Copyright © 2020-2023  润新知