redis基础数据结构(二) 内存管理模块

本文介绍了Redis内存管理方式,包括tcmalloc和jemalloc的选择及应用。重点讲解了jemalloc的性能优势,以及如何通过宏控制内存分配和释放,确保内存管理高效运行。同时探讨了进程内存管理方法,通过读取/proc/pid/stat中的RSS字段来获取进程内存使用情况。

redis可选内存管理方式为tcmalloc或jemalloc,用宏控制,一般用jemalloc性能最好,底层调用remalloc接口,redis的内存管理模块只是封装函数,内存管理在zmalloc.h和zmalloc.c中。

zmalloc.c中定义一个全局变量used_memory和两个用于管理user_memory的宏,如下

#define update_zmalloc_stat_alloc(__n) do { \
    size_t _n = (__n); \
    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
    atomicIncr(used_memory,__n); \
} while(0)

#define update_zmalloc_stat_free(__n) do { \
    size_t _n = (__n); \
    if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \
    atomicDecr(used_memory,__n); \
} while(0)

static size_t used_memory = 0;
pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER;

其中atomicIncr和atomicDecr是原子操作,通过互斥锁实现,内存补齐使用位操作以保证性能,used_memory保存的是实际使用的内存大小

内存分配函数zmalloc:

void *zmalloc(size_t size) {
    void *ptr = malloc(size+PREFIX_SIZE);

    if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
    update_zmalloc_stat_alloc(zmalloc_size(ptr));
    return ptr;
#else
    *((size_t*)ptr) = size;
    update_zmalloc_stat_alloc(size+PREFIX_SIZE);
    return (char*)ptr+PREFIX_SIZE;
#endif
}

给ptr分配内存时,增加size_t大小内存,用于保存实际使用的内存大小,返回给调用者的指针越过这个大小的地址。其余内存管理函数calloc和realloc等实现方式和malloc类似

进程内存管理:

size_t zmalloc_get_rss(void) {
    int page = sysconf(_SC_PAGESIZE);
    size_t rss;
    char buf[4096];
    char filename[256];
    int fd, count;
    char *p, *x;

    snprintf(filename,256,"/proc/%d/stat",getpid());
    if ((fd = open(filename,O_RDONLY)) == -1) return 0;
    if (read(fd,buf,4096) <= 0) {
        close(fd);
        return 0;
    }
    close(fd);

    p = buf;
    count = 23; /* RSS is the 24th field in /proc/<pid>/stat */
    while(p && count--) {
        p = strchr(p,' ');
        if (p) p++;
    }
    if (!p) return 0;
    x = strchr(p,' ');
    if (!x) return 0;
    *x = '\0';

    rss = strtoll(p,NULL,10);
    rss *= page;
    return rss;
}
通过读取/proc/pid/stat中的rss字段,涉及文件读取,显然性能很差。内存碎片率用rss/used_memory计算,此外zmalloc模块还提供了读取smap等内存接口,具体含义参见linux进程内存管理机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值