1. Redis内存管理通过在zmalloc.h和zmalloc.c中重写c语言对内存的管理来完成的。
redis内存管理 | c内存管理 | 原型 | 作用 |
zmalloc | malloc | void *malloc(unsigned int num_bytes); | 分配一块指定大小的内存区域,并返回指向该区域头部的指针,分配失败则返回NULL |
zcalloc | calloc | void *calloc(unsigned n, unsigned size); | 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。 |
zrealloc | realloc | oid *realloc(void *mem_address, unsigned int newsize); | 先判断当前的 指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定 的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用 free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。 |
zfree | free | void free(void *ptr) | 释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后可在调用malloc、realloc以及calloc函数来再分配。 |
封装就是为了屏蔽底层平台的差异,同时方便自己实现相关的统计函数。
定义平台之间的差异,主要是tcmalloc(google)、jemalloc(facebook)、苹果平台。
具体来说就是:
- 若系统中存在Google的TC_MALLOC库,则使用tc_malloc一族函数代替原本的malloc一族函数。
- 若系统中存在facebook的JE_MALLOC库,则使用je_malloc一族函数替换原来的malloc一族函数。
- 若当前系统是Mac系统或者其它系统,则使用<malloc/malloc.h>中的内存分配函数。
/* Double expansion needed for stringification of macro values. */ #define __xstr(s) __str(s) #define __str(s) #s #if defined(USE_TCMALLOC) #define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR)) #include <google/tcmalloc.h> #if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1) #define HAVE_MALLOC_SIZE 1 #define zmalloc_size(p) tc_malloc_size(p) #else #error "Newer version of tcmalloc required" #endif #elif defined(USE_JEMALLOC) #define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX)) #include <jemalloc/jemalloc.h> #if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2) #define HAVE_MALLOC_SIZE 1 #define zmalloc_size(p) je_malloc_usable_size(p) #else #error "Newer version of jemalloc required" #endif #elif defined(__APPLE__) #include <malloc/malloc.h> #define HAVE_MALLOC_SIZE 1 #define zmalloc_size(p) malloc_size(p) #endif
具体如下:
/* Explicitly override malloc/free etc when using tcmalloc. */ #if defined(USE_TCMALLOC) #define malloc(size) tc_malloc(size) #define calloc(count,size) tc_calloc(count,size) #define realloc(ptr,size) tc_realloc(ptr,size) #define free(ptr) tc_free(ptr) #elif defined(USE_JEMALLOC) #define malloc(size) je_malloc(size) #define calloc(count,size) je_calloc(count,size) #define realloc(ptr,size) je_realloc(ptr,size) #define free(ptr) je_free(ptr) #endif #ifdef HAVE_ATOMIC #define update_zmalloc_stat_add(__n) __sync_add_and_fetch(&used_memory, (__n)) #define update_zmalloc_stat_sub(__n) __sync_sub_and_fetch(&used_memory, (__n)) #else #define update_zmalloc_stat_add(__n) do { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory += (__n); \ pthread_mutex_unlock(&used_memory_mutex); \ } while(0) #define update_zmalloc_stat_sub(__n) do { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory -= (__n); \ pthread_mutex_unlock(&used_memory_mutex); \ } while(0) #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实现
void *zmalloc(size_t size) { void *ptr = malloc(size+PREFIX_SIZE); if (!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)); //更新分配内存的状态。处理线程安全和线程不安全 return ptr; #else *((size_t*)ptr) = size; update_zmalloc_stat_alloc(size+PREFIX_SIZE); return (char*)ptr+PREFIX_SIZE; #endif }
#define update_zmalloc_stat_alloc(__n) do { \ size_t _n = (__n); \ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ if (zmalloc_thread_safe) { \ update_zmalloc_stat_add(_n); \ } else { \ used_memory += _n; \ } \ } while(0) #ifdef HAVE_ATOMIC #define update_zmalloc_stat_add(__n) __sync_add_and_fetch(&used_memory, (__n)) #define update_zmalloc_stat_sub(__n) __sync_sub_and_fetch(&used_memory, (__n)) #else #define update_zmalloc_stat_add(__n) do { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory += (__n); \ pthread_mutex_unlock(&used_memory_mutex); \ } while(0) #define update_zmalloc_stat_sub(__n) do { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory -= (__n); \ pthread_mutex_unlock(&used_memory_mutex); \ } while(0) #endif
说明
int pthread_mutex_lock(pthread_mutex_t *mutex);
当pthread_mutex_lock()返回时,该互斥锁已被锁定。线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。
int pthread_mutex_unlock(pthread_mutex_t *mutex);和上面的函数为一对。
其它函数的实现类似。
http://www.cnblogs.com/davidwang456/p/3504563.html
相关推荐
首先,我们来看`Tomcat-Redis-Session-Manager`的核心功能:它将Tomcat默认的内存会话管理替换为基于Redis的分布式会话管理。这主要涉及两个关键组件:`RedisSessionManager`和`RedisSessionHandlerWrapper`。 `...
通过阅读源码,我们可以深入理解其内部实现机制,比如如何序列化和反序列化session对象,以及如何处理并发和超时问题。而README通常会提供详细的安装和使用指南,包括环境需求、配置参数的解释以及可能出现的问题及...
通过这个环境,开发者可以深入理解Redis的内部工作原理,对源码进行修改或扩展,以满足特定需求。 压缩包内的文件可能包括以下内容: 1. `src`目录:包含Redis服务器的源代码文件,如`redis-server.exe`用于启动...
Redis,全称Remote Dictionary Server,是一款...总的来说,"Redis--参考资料即总结"这个主题将带领读者深入Redis的世界,从基本概念到高级特性,从源码剖析到工具使用,全面掌握这个强大的键值存储系统的方方面面。
6. **内存管理优化**:Redis 3.x继续优化内存管理,包括更好的内存压缩和更智能的内存回收策略,以降低内存占用。 7. **性能提升**:通过对内部数据结构的调整和算法优化,3.x在处理大量请求时性能得到显著提升。 ...
8. **内存管理**:Redis 使用自己定制的内存管理机制,通过 LRU(Least Recently Used)策略进行内存淘汰,保证在内存限制下尽可能高效地使用内存。 9. **集群**:Redis 3.0 引入了 Redis Cluster,提供了一种分布式...
首先,从源码编译意味着你可以深入了解其内部工作原理,同时可以根据需求进行定制化修改。对于开发者来说,这是一个非常宝贵的学习和调试资源。其次,新版本可能包含性能提升,如更快的数据读写速度,更优化的内存...
5. **源代码**:包含的`redis-win-3.2.100.zip`文件提供了Redis的源代码,对于开发者而言,可以查看源码、学习内部实现或进行二次开发。如果需要编译源码,需要安装Visual Studio等开发环境,并遵循官方的编译指南。...
Redis是世界上最受欢迎的内存数据存储系统之一,常用于构建高性能、低延迟的数据缓存和数据库。Redis Python 客户端,即redis-py,是Python社区广泛使用的与Redis服务器交互的库。`redis-py-cluster`是这个客户端的...
Redis-3.2.11.tar.gz 文件是Redis 3.2.11版本的源代码包,通过这个文件,我们可以了解Redis的内部实现并进行自定义编译安装。 首先,安装Redis通常涉及以下步骤: 1. **解压源码**:使用`tar -zxvf redis-3.2.11....
- Redis 7.0.2可能通过优化内部算法和数据结构,提升了读写速度,减少了内存占用,进一步增强了其作为高性能缓存系统的地位。 - 并行命令执行也可能得到了改善,允许在单个连接上并行处理多个命令,提高了吞吐量。...
本文将深入探讨 Redis 3.2 的关键特性,以及64位系统下运行 Redis 的优势。 首先,Redis 3.2 引入了多种新功能和改进,其中最为显著的是LUA脚本的原子执行。在之前版本中,虽然LUA脚本可以在服务器端运行,但执行...
这个2020.1.0版本的特色在于它是通过源码打包,这意味着用户可以深入了解其内部工作原理,并且没有使用上的任何限制,为开发人员和运维人员提供了极大的便利。 这款软件的主要功能包括: 1. **连接管理**:用户...
本文将深入探讨 Redis 5.0.9 和 Another-Redis-Desktop-Manager 1.3.6 的相关知识。 首先,我们关注的是 Redis-x64-5.0.9.msi,这是一个针对Windows操作系统的64位版本的Redis安装包。Redis 5.0.9 是 Redis 的一个...
Common-Pool2-source.rar则包含了Common-Pool2的源代码,开发者可以通过阅读源码来了解其内部工作原理,进行更深入的定制或优化。 在使用Redis3.2+jedis2.8.jar进行Java开发时,首先需要在项目中引入Jedis库,配置...
在本文中,我们将深入探讨Redis的基础概念、主要功能、6.2.3版本的新特性以及在Windows上的安装和使用方法。 1. Redis基础: Redis是一个开源的、基于内存的数据结构存储系统,支持多种数据类型,如字符串、哈希、...
4. **性能优化**:Redis 4.0对内部结构进行了优化,提高了读写速度和内存效率。此外,还改进了命令执行的并发性,尤其是在高并发场景下。 5. **AOF重写策略**:追加式日志(Append Only File,AOF)的重写策略也...
Redis是世界上最受欢迎的开源内存数据结构存储系统,它作为一个键值数据库被广泛应用于缓存、消息中间件、计数器等...通过编译和安装,开发者可以深入了解其内部工作原理,同时享受到Redis提供的高效内存数据处理能力。
9. **性能提升**:通过内部算法优化和内存管理改进,Redis 7.0在读写速度、内存效率等方面都有所提升。 安装Redis 7.0通常涉及以下步骤: 1. 下载源码包,例如`redis-7.0.4.tar.gz`。 2. 解压压缩包:`tar -zxvf ...
Redis是世界上最受欢迎的内存数据存储系统之一,尤其在高性能、低延迟的数据访问需求场景中表现卓越。这个"redis-4.0.11"安装包是Redis的一个特定版本,适用于那些需要稳定性和兼容性的项目。在本文中,我们将深入...