加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

深入redis内部--内存管理

发布时间:2020-12-16 04:45:02 所属栏目:安全 来源:网络整理
导读:1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c语言对内存的管理来完成的。 封装就是为了屏蔽底层平台的差异,同时方便自己实现相关的统计函数。 定义平台之间的差异,主要是tcmalloc(google)、jemalloc(facebook)、苹果平台。 具体来说就是: 若系

1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c语言对内存的管理来完成的。

封装就是为了屏蔽底层平台的差异,同时方便自己实现相关的统计函数。

定义平台之间的差异,主要是tcmalloc(google)、jemalloc(facebook)、苹果平台。

具体来说就是:

  • 若系统中存在Google的TC_MALLOC库,则使用tc_malloc一族函数代替原本的malloc一族函数。
  • 若系统中存在facebook的JE_MALLOC库,则使用je_malloc一族函数替换原来的malloc一族函数。
  • 若当前系统是Mac系统或者其它系统,则使用中的内存分配函数。
__xstr(s) __str(s) __str(s) #s

<span style="color: #0000ff;">#if defined(USE_TCMALLOC)
<span style="color: #0000ff;">#define ZMALLOC_LIB ("tcmalloc-" xstr(TC_VERSION_MAJOR) "." xstr(TC_VERSION_MINOR))<span style="color: #000000;">

include <google/tcmalloc.h>

<span style="color: #0000ff;">#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
<span style="color: #0000ff;">#define HAVE_MALLOC_SIZE 1
<span style="color: #0000ff;">#define zmalloc_size(p) tc_malloc_size(p)
<span style="color: #0000ff;">#else
<span style="color: #0000ff;">#error "Newer version of tcmalloc required"
<span style="color: #0000ff;">#endif

<span style="color: #0000ff;">#elif defined(USE_JEMALLOC)
<span style="color: #0000ff;">#define ZMALLOC_LIB ("jemalloc-" xstr(JEMALLOC_VERSION_MAJOR) "." xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))<span style="color: #000000;">

include <jemalloc/jemalloc.h>

<span style="color: #0000ff;">#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
<span style="color: #0000ff;">#define HAVE_MALLOC_SIZE 1
<span style="color: #0000ff;">#define zmalloc_size(p) je_malloc_usable_size(p)
<span style="color: #0000ff;">#else
<span style="color: #0000ff;">#error "Newer version of jemalloc required"
<span style="color: #0000ff;">#endif

<span style="color: #0000ff;">#elif defined(APPLE)<span style="color: #000000;">

include <malloc/malloc.h>

<span style="color: #0000ff;">#define HAVE_MALLOC_SIZE 1
<span style="color: #0000ff;">#define zmalloc_size(p) malloc_size(p)
<span style="color: #0000ff;">#endif

具体如下:

defined(USE_TCMALLOC) malloc(size) tc_malloc(size) calloc(count,size) tc_calloc(count,size) realloc(ptr,size) tc_realloc(ptr,size) free(ptr) tc_free(ptr) defined(USE_JEMALLOC) malloc(size) je_malloc(size) calloc(count,size) je_calloc(count,size) je_realloc(ptr,size) free(ptr) je_free(ptr) ifdef HAVE_ATOMIC

<span style="color: #0000ff;">#define update_zmalloc_stat_add(n) sync_add_and_fetch(&used_memory,(n))
<span style="color: #0000ff;">#define update_zmalloc_stat_sub(n) sync_sub_and_fetch(&used_memory,(__n))
<span style="color: #0000ff;">#else
<span style="color: #0000ff;">#define update_zmalloc_stat_add(
n) do { &;span style="color: #000000;">
pthread_mutex_lock(&<span style="color: #000000;">used_memory_mutex);
used_memory +=<span style="color: #000000;"> (__n);
pthread_mutex_unlock(&<span style="color: #000000;">used_memory_mutex);
} <span style="color: #0000ff;">while(<span style="color: #800080;">0<span style="color: #000000;">)

<span style="color: #0000ff;">#define update_zmalloc_stat_sub(__n) do { &;span style="color: #000000;">
pthread_mutex_lock(&<span style="color: #000000;">used_memory_mutex);
used_memory -=<span style="color: #000000;"> (__n);
pthread_mutex_unlock(&<span style="color: #000000;">used_memory_mutex);
} <span style="color: #0000ff;">while(<span style="color: #800080;">0<span style="color: #000000;">)

<span style="color: #0000ff;">#endif

说明:

Both libraries try to de-contention memory acquire by having threads pick the memory from different caches,but they have different strategies:


  • jemalloc?(used by Facebook) maintains a cache per thread
  • tcmalloc?(from Google) maintains a pool of caches,and threads develop a "natural" affinity for a cache,but may change

This led,once again if I remember correctly,to an important difference in term of thread management.


  • jemalloc?is faster if threads are static,for example using pools
  • tcmalloc?is faster when threads are created/destructed

1.1 zmalloc实现? ? ??

* *ptr = malloc(size+</span><span style="color: #0000ff;"&gt;if</span> (!<span style="color: #000000;"&gt;ptr) zmalloc_oom_handler(size); //如果没有发生内存溢出,则使用的分配方式static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;

ifdef HAVE_MALLOC_SIZE //HAVE_MALLOC_SIZE用来确定系统是否有函数malloc_size,定义如上所示。

update_zmalloc_stat_alloc(zmalloc_size(ptr)); //更新分配内存的状态。处理线程安全和线程不安全
</span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; ptr;

<span style="color: #0000ff;">#else
((size_t)ptr) =<span style="color: #000000;"> size;
update_zmalloc_stat_alloc(size+<span style="color: #000000;">PREFIX_SIZE);
<span style="color: #0000ff;">return (<span style="color: #0000ff;">char*)ptr+<span style="color: #000000;">PREFIX_SIZE;
<span style="color: #0000ff;">#endif<span style="color: #000000;">
}

<div class="cnblogs_code">

 update_zmalloc_stat_alloc(__n) do { = (_n&(()-)) _n += ()-(_n&(()-+=(ifdef HAVE_ATOMIC

<span style="color: #0000ff;">#define update_zmalloc_stat_add(n) sync_add_and_fetch(&used_memory,(n))
<span style="color: #0000ff;">#else
<span style="color: #0000ff;">#define update_zmalloc_stat_add(__n) do { &;span style="color: #000000;">
pthread_mutex_lock(&<span style="color: #000000;">used_memory_mutex);
used_memory +=<span style="color: #000000;"> (
n);
pthread_mutex_unlock(&<span style="color: #000000;">used_memory_mutex);
} <span style="color: #0000ff;">while(<span style="color: #800080;">0<span style="color: #000000;">)

<span style="color: #0000ff;">#define update_zmalloc_stat_sub(__n) do { &;span style="color: #000000;">
pthread_mutex_lock(&<span style="color: #000000;">used_memory_mutex);
used_memory -=<span style="color: #000000;"> (__n);
pthread_mutex_unlock(&<span style="color: #000000;">used_memory_mutex);
} <span style="color: #0000ff;">while(<span style="color: #800080;">0<span style="color: #000000;">)

<span style="color: #0000ff;">#endif

说明

int pthread_mutex_lock(pthread_mutex_t *mutex);

当pthread_mutex_lock()返回时,该已被锁定。调用该函数让上锁,如果该已被另一个锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。

int pthread_mutex_unlock(pthread_mutex_t *mutex);和上面的函数为一对。

其它函数的实现类似。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!