Redis对象——内存回收,对象共享和空转时长

一. 内存回收 

        因为C语言不具备内存回收功能,所以Redis在自己的对象系统中构建了一个引用计数技术实现内存回收机制。通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。

        内每一个对象的引用计数信息由redisObject结构的refcount属性记录:

typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or* LFU data (least significant 8 bits frequency* and most significant 16 bits access time). */int refcount;void *ptr;
} robj;

        对象的引用计数信息会随着对象的使用状态而不断变化:

  • 在创建一个新对象时,引用计数的值会被初始化为1。
  • 当对象被一个新程序使用时,他的引用计数会被增1。
  • 当对象不被程序使用时,他的引用计数会被减1。
  • 当对象的引用计数值变为0时,对象所占有的内存会被释放掉。

        下面是对引用计数进行操作的接口:

//创建对象
robj *createObject(int type, void *ptr);
robj *createStringObject(const char *ptr, size_t len);
robj *createRawStringObject(const char *ptr, size_t len);
robj *createEmbeddedStringObject(const char *ptr, size_t len);
robj *createStringObjectFromLongLong(long long value);
robj *createStringObjectFromLongLongForValue(long long value);
robj *createStringObjectFromLongDouble(long double value, int humanfriendly);
robj *createQuicklistObject(void);
robj *createZiplistObject(void);
robj *createSetObject(void);
robj *createIntsetObject(void);
robj *createHashObject(void);
robj *createZsetObject(void);
robj *createZsetZiplistObject(void);
robj *createStreamObject(void);
robj *createModuleObject(moduleType *mt, void *value);//对引用计数加1
void incrRefCount(robj *o) {if (o->refcount < OBJ_FIRST_SPECIAL_REFCOUNT) {o->refcount++;} else {if (o->refcount == OBJ_SHARED_REFCOUNT) {/* Nothing to do: this refcount is immutable. */} else if (o->refcount == OBJ_STATIC_REFCOUNT) {serverPanic("You tried to retain an object allocated in the stack");}}
}
//对引用计数减1,减为0时释放对象内存
void decrRefCount(robj *o) {if (o->refcount == 1) {switch(o->type) {case OBJ_STRING: freeStringObject(o); break;case OBJ_LIST: freeListObject(o); break;case OBJ_SET: freeSetObject(o); break;case OBJ_ZSET: freeZsetObject(o); break;case OBJ_HASH: freeHashObject(o); break;case OBJ_MODULE: freeModuleObject(o); break;case OBJ_STREAM: freeStreamObject(o); break;default: serverPanic("Unknown object type"); break;}zfree(o);} else {if (o->refcount <= 0) serverPanic("decrRefCount against refcount <= 0");if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount--;}
}

        对象的整个生命周期可以划分为创建对象,操作对象,释放对象三个阶段。

二. 对象共享

        Redis除了用于实现引用计数内存回收机制之外,对象的引用计数属性还带由对象共享的作用。

        举个例子:假设键A创建一个包含整数值100的字符串对象作为值对象,如果这时键B也要创建一个同样保存了整数值100的字符串对象作为值对象。Redis服务器的做法是,让键A和键B共享同一个字符串对象。也就是将数据库的键的值指针指向一个现有的值对象,将共享的值对象的引用计数加一。

        这样的共享对象机制的作用是节约内存。 

        目前来说,Redis会在初始化服务器时,创建一万个字符串对象,这些对象包含从0到9999的所有整数值,当服务器需要用到值为0到9999的字符串对象时,服务器会使用到这些共享对象。而不是新创建对象。

        注意:创建共享字符串对象的数量可以通过redis.h/REDIS_SHARED_INTEGERS常量修改。

        下面的命令佐证了只有值是0到9999整数的字符串对象作为共享对象:

127.0.0.1:6379> set A 10000
OK
127.0.0.1:6379> OBJECT REFCOUNT A
(integer) 1
127.0.0.1:6379> set B 10000
OK
127.0.0.1:6379> OBJECT REFCOUNT A
(integer) 1
127.0.0.1:6379> OBJECT REFCOUNT B
(integer) 1

        另外,这些共享对象不单单只有字符串键可以使用,那些在数据结构嵌套了字符串对象的对象(linkedlist编码的列表对象,hashtable编码的哈希对象,hashtable编码的集合对象,zset编码的有序集合对象)都可以使用这些共享对象。

为什么Redis不包含字符串的对象:

        当服务器考虑将一个共享对象设置为键的值对象时,程序需要先检查给定的共享对象和键想创建的目标对象是否完全相同,只有在共享对象和目标对象完全相同的情况下,程序才会将共享对象用作键的值对象。当共享对象保存的值越复杂,验证共享对象和目标对象是否相同所需要的复杂度越高。

  • 假如共享对象是整数值的字符串对象,那么验证操作的复杂度为O(1)。
  • 假如共享对象是字符串值的字符串对象,那么验证操作复杂度为O(N)。
  • 假如共享对象是包含了多个值(或对象)的对象,比如列表对象或哈希对象,那么验证操作的复杂度将会是O(N^2)。

        因此,尽管共享对象可以节约内存,但是为了效率着想,Redis只对包含整数值的字符串对象进行共享。

三. 对象时间空转时长

        redisObject对象中还有一个属性lru,记录了对象最后一次被命令程序访问的时间。OBJECT IDLETIME命令可以打印出给定键的空转时长,这个空转时长就是通过将当前时间减去键的值对象的lru时间计算出来的。OBJECT IDLETIME命令在执行时不会修改lru属性。

        对象的空转时长出来可以使用OBJECT IDLETIME命令查看外,另外一个作用是:如果服务器打开了maxmemory选项,并且服务器的回收算法为volatile-lru或者allkeys-lru,那么当服务器占用的内存数超过maxmemory的值时,空转时长较高的那部分键会被服务器优先释放,从而回收内存。

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/223439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平台工程与 DevOps 和 SRE 有何不同?

在现代软件开发和运营的动态领域中 &#xff0c;平台工程、DevOps 和站点可靠性工程 (SRE) 等术语 经常使用&#xff0c;有时可以互换使用&#xff0c;这常常会导致进入或浏览这些领域的专业人员感到困惑。了解这些概念之间的细微差别对于努力构建强大且可扩展的系统的组织至关…

国产Apple Find My「查找」认证芯片-伦茨科技ST17H6x芯片

深圳市伦茨科技有限公司&#xff08;以下简称“伦茨科技”&#xff09;发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家&#xff0c;该平台提供可通过Apple Find My认证的Apple查找&#xff08;Find My&#xff09;功能集成解决方案。…

连连看游戏

连通块记忆性递归的综合运用 这里x&#xff0c;y的设置反我平常的习惯&#xff0c;搞得我有点晕 实际上可以一输入就交换x&#xff0c;y的数据的 如果设置y1为全局变量的话会warning&#xff1a; warning: built-in function y1 declared as non-function 所以我改成p和q了…

一些好用的VSCode扩展

可以在扩展这里直接搜索需要的扩展&#xff0c;点击安装即可。 1.Chinese 中文扩展&#xff0c;就是说虽然咱们懂点英语&#xff0c;但还是中文看着方便 2.Auto Rename Tag 当你重命名一个HTML 标签时&#xff0c;会自动重命名与他配对的HTML 标签 当你选择h4这个标签时&…

系列三、DDL

一、DDL 1.1、概述 DDL是英文单词Data Definition Language的缩写&#xff0c;中文意思为数据定义语言&#xff0c;是用来定义数据库对象(数据库&#xff0c;表&#xff0c;字段)的。 1.2、数据库操作 1.2.1、查询所有数据库 show databases; 1.2.2、创建数据库 # 语法 cre…

云原生基础入门概念

文章目录 云原生的概念云原生的关键技术为何选择云原生&#xff1f;云原生的实际应用 当谈及现代软件开发和IT基础架构时&#xff0c;云原生成为了一个备受关注的话题。它代表了一种软件架构和开发方法&#xff0c;旨在充分利用云计算环境的优势&#xff0c;以提高应用程序的可…

【AI美图】第02期效果图,AI人工智能全自动绘画,美图欣赏

今天给大家献上一组最新提示词 参照图生成图像 依据参照图生成新的图像需要掌握一些技巧&#xff0c;以下是一些可能有用的技巧&#xff1a; 观察参照图&#xff1a;在开始生成新图像之前&#xff0c;仔细观察参照图是非常重要的。你需要了解图像的布局、颜色、线条、细节等…

新一代“垫图”神器,IP-Adapter的完整应用解读

导读 不用训练lora&#xff0c;一张图就能实现风格迁移&#xff0c;还支持多图多特征提取&#xff0c;同时强大的拓展能力还可接入动态prompt矩阵、controlnet等等&#xff0c;这就是IP-Adapter&#xff0c;一种全新的“垫图”方式&#xff0c;让你的AIGC之旅更加高效轻松。 …

智慧工地源码(微服务+Java+Springcloud+Vue+MySQL)

智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台&#xff0c;是一种全新的管理模式&#xff0c;能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度&#xff0c;以及施工过程管理的进度、质量、安全三…

Python Socket编程

Python Socket编程 文章目录 Python Socket编程1. 弄懂HTTP、Socket、TCP这几个概念五层网络模型 2. client和server实现通信Socket编程模式指南代码实现 3. socket实现聊天和多用户连接4. socket模拟http请求5. socket使用I/O多路复用模式模拟http请求 1. 弄懂HTTP、Socket、T…

51单片机的外部中断的以及相关寄存器的讲解

中断系统 本文主要涉及8051单片机的中断系统的讲解与使用 其中包括中断相关寄存器的介绍与使用以及外部中断初始化的代码分析。 文章目录 中断系统一、 中断的介绍二、 中断结构及相关寄存器2.1 中断源 2.2 中断请求控制器2.2.1 TCON寄存器2.2.2 SCON寄存器2.2.3 中断允许寄存器…

【每日一题】【12.15】2415.反转二叉树的奇数层

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 2415. 反转二叉树的奇数层https://leetcode.cn/problems/reverse-odd-levels-of-binary-tree/ 今天终于碰到了一个mid题目&#x…

数据库常用分库分表方案

为什么需要分库分表 分库分表是因应数据库处理大规模数据时所面临的挑战而出现的解决方案. // 提高性能 单个数据库在数据量增加时容易出现性能瓶颈。分库分表可以减轻单个数据库的负担&#xff0c;提高系统的读写性能和响应速度. // 提高并发能力 大量用户同时访问数据库可能…

N-Channel Trench Power MOSFET FMA30H150SL

FMA30H150SL N-Channel Trench Power MOSFET FMA30H150SL Application &#xff1a;  LCD TV  Notebook  Elevator  Inductive heating  Power tools  Broadband FMA30H150SL Features &#xff1a;  30V,150A  RDS(ON)2.4mΩ (Typ.) VGS 10V …

若依 ruoyi-vue3 集成aj-captcha实现滑块、文字点选验证码

目录 0. 前言0.1 说明 1. 后端部分1.1 添加依赖1.2. 修改 application.yml1.3. 新增 CaptchaRedisService 类1.4. 添加必须文件1.5. 移除不需要的类1.6. 修改登录方法1.7. 新增验证码开关获取接口1.8. 允许匿名访问 2. 前端部分&#xff08;Vue3&#xff09;2.1. 新增依赖 cryp…

“一键调整尺寸,轻松完成视频批量剪辑:批量放大视频尺寸“

你是否曾经遇到过需要批量调整视频尺寸的情况&#xff1f;无论是为了适应不同的播放平台&#xff0c;还是为了满足客户的特定需求&#xff0c;批量调整视频尺寸都是一项繁琐而耗时的工作。但是&#xff0c;现在有一种方法可以让你轻松完成这项任务&#xff0c;那就是使用我们的…

Excel高效办公:文秘与行政办公的智能化革新

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f91f; 代理 IP 推荐&#xff1a;&#x1f449;品易 HTTP 代理 IP &#x1f485; 想寻找共同学习交流的小伙伴&#xff0c…

超声波清洗机怎么买不会踩坑?减少踩坑机会超声波清洗机推荐

在当今快节奏的生活中&#xff0c;超声波清洗机已经成为了我们生活中不可或缺的助手。无论是清洗餐具、首饰&#xff0c;还是清洗医疗设备、实验室仪器&#xff0c;超声波清洗机都能以其高效、便捷的特性&#xff0c;帮助我们解决各种清洁难题。然而&#xff0c;面对市场上琳琅…

ZeroSSL-ip证书配置

1.申请证书 Free SSL Certificates and SSL Tools - ZeroSSL 2.填入公网 IP 地址 3.选择90天免费 SSL 4.自动生成CSR 5.选择文件验证方式 使用80端口,建立对应的文件并进行访问测试 6. 进行认证 7.下载证书并进行配置 8.合并ssl证书 对于 Nginx 服务器,需要将 ca_bundle.crt…

ARM KEIL 安装

根据设备类型安装开发工具及环境 Arm,Cortex ----> MDK-Arm 8051 ----> C51 80251 ----> C251 C166,XC166,XC2000 MCU设备 ----> C155 填写信息提交后下载 点击MDK539.EXE下载 : MDK539.EXE 双击MDK539安装 点击Next 默认安装路径,点击Ne…