在上一节介绍zmalloc/zfree函数时,我们看到redis会调用increment_used_memory/decrement_used_memory,这两个宏其实就是对static变量used_memory进行指定大小的增加/减少,该变量保存了redis所使用的内存大小:
// sizeof(long)字节对齐 #define increment_used_memory(__n) do { \ size_t _n = (__n); \ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ if (zmalloc_thread_safe) { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory += _n; \ pthread_mutex_unlock(&used_memory_mutex); \ } else { \ used_memory += _n; \ } \ } while(0)
分配内存的线程安全性是由底层系统的malloc系列函数来保证的,而used_memory变量的线程安全性取决于线程锁zmalloc_thread_safe的值。由于redis处理客户端连接是单进程单线程事件多路循环的,那么就有一个疑问,redis在什么情况下,需要多线程保护了?在后续的介绍中,我们会看到,redis的虚拟内存(VM)可能启用多线程。 继续阅读