如何构建一个对象池并使用
1.背景
在项目中,如果频繁的通过new 创建对象,之后让gc再去回收,这就很容易造成内存抖动,并且频繁的GC本身也会消耗内存,这样就很容易在一瞬间造成OOM 内存溢出,因为瞬间申请大量内存会造成内存占用突然升高,如果GC 还没来的及回收,或者频繁GC,内存就会居高不下,这时有两种处理方式,一个是减少对象的创建,一个是复用对象。
2. 对象复用的基本原理
所谓对象复用,就是在对象创建使用完成后将对象内部的数据清除,然后将对象放到缓存中,等到下次需要创建新对象时拿出来复用,这样一来一回,只需要占用固定的内存就可以,不用每次都去new 一个对象申请内存,即避免的内存抖动,又避免了频繁GC,造成可能的稳定性问题,但是也有一个小弊端,就是这块缓存的对象所占的对象是固定的,无法随着GC来回收,如果需要回收需要我们手动处理,所以这个就需要我们对使用场景来评估。
3.如何构建一个对象池
1.需要有一个合适的对象
2.定一个对象池的大小
3.处理对象的回收
4.在核实的位置获取对象池中数据并且在使用完成后回收
4. 构建一个对象池
public class MapCache extends HashMap<String, String> {private static final String TAG = "MapCache";//下一条对象MapCache next;public static final Object sPoolSync = new Object ();// 链表首个对象private static MapCache sPool;//当前链表个数private static int sPoolSize = 0;//可缓存的最大空闲对象数量,超出后将开始new 对象,由GC 处理回收private static final int MAX_POOL_SIZE = 50;@Overridepublic void clear() {recycle ();}/*** 获取map对像,如果对象池存在空闲对象,就从头部取出一个空对象返回* 否则new 一个新对象。*/public static MapCache obtain() {synchronized (sPoolSync) {if (sPool != null) {MapCache m = sPool;sPool = m.next;m.next = null;sPoolSize--;// 返回链表头部对象return m;}}return new MapCache ();}/*** 回收对象资源*/private void recycle() {super.clear ();synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;// 将当前消息放到链表头部sPool = this;//链表消息池对象增加1sPoolSize++;}}}public static MapCache createCacheMap(Map<String, String> args) {MapCache map = obtain ();for (Map.Entry<?, ?> entry : args.entrySet ()) {String key = (String) entry.getKey ();if (key == null) {Log.e (TAG, "CreateMap error: key == null");continue;}map.put (key, (String) entry.getValue ());}return map;}private static boolean isMapCache(Map mapCache) {if (mapCache instanceof MapCache) {return true;}return false;}public static MapCache createMap(Map mapCache) {if (mapCache==null || mapCache.size ()<=0) {return null;}if (isMapCache(mapCache)) {return (MapCache) mapCache;}return createCacheMap (mapCache);}}
其实还算简单,基本原理就是定一个对象池大小,用一个链表来存储对象,然后定义一个静态的头部对象sPoolSync,然后定义这个头部对象的next 指向的下一个对象,这样就形成了一个链表的对象池。
3.1 获取对象
当通过obtain() 方法来获取一个对象时,如果链表中有缓存的对象数据就取出链表首部的对象,然后将他的下一个对象指向头部对象,然后将对象池减一个,如果没有足够的对象或者首次调用,那就new 一个对象返回。
3.2 对象的回收
对象内容的回收recycle()需要根据不同的对象定义来处理,就比如我这定义的HashMap,使用完成后只需要调用clear 方法将原数据清空,然后将这个对象加入到线程池中即可。
具体操作 就是先将当前的链表头部对象指向当前的空闲对像的next,然后将空闲该对象 指向头部静态对像,然后对象池加一,这样就顺利将空闲对像加到链表头部。
相关文章:
如何构建一个对象池并使用
1.背景 在项目中,如果频繁的通过new 创建对象,之后让gc再去回收,这就很容易造成内存抖动,并且频繁的GC本身也会消耗内存,这样就很容易在一瞬间造成OOM 内存溢出,因为瞬间申请大量内存会造成内存占用突然升…...
【沁恒蓝牙mesh】CH58x USB功能开发记录(三)
本博文主要记录 ,【沁恒蓝牙mesh】CH58x USB功能开发记录(三),数据收发基于寄存器级别解释 💖 作者简介:大家好,我是喜欢记录零碎知识点的小菜鸟。😎📝 个人主页…...
2023国赛数学建模D题思路分析
文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…...
linux 学习————LNMP之分布式部署
目录 一、概述 二、LNMP环境部署 三、配置nginx 四、 配置php使nginx能够解析.php 五、配置mysql 六、配置discuz进行登录论坛访问测试 一、概述 LNMP代表 Linux、Nginx、MySQL、PHP,是一种常用的服务器架构。它由以下组件组成: Linux:作…...
第八课 双重所有格和不定代词
系列文章目录 文章目录 系列文章目录前言一、of s 的所有格1、of 有生命的名词 ’s2、of 名词性物主代词3、小结 二、反身代词1、作宾语和介词宾语2、作表语3、作固定惯语 三、相互代词四、指示代词 Such 和 Same 的用法 前言 一、of s 的所有格 1、of 有生命的名词 ’s 2、…...
使用xrdp协议远程桌面控制树莓派,无需公网IP!
远程桌面控制树莓派,我们可以用xrdp协议来实现,它内部使用的是windows远程桌面的协议。我们只需要在树莓派上安装xrdp,就可以在同个局域网下远程桌面控制树莓派。 而如果需要在公网下远程桌面控制树莓派,可以通过cpolar内网穿透&…...
数据结构【图的类型定义和存储结构】
数据结构之图 图的定义和概念图的定义图的术语 图的类型定义图的存储结构数组(邻接矩阵)表示法无向图的邻接矩阵表示法有向图的邻接矩阵表示法网(即有权图)的邻接矩阵表示法 邻接矩阵的ADT定义邻接表(链式)…...
PHP Smarty如何进行调试和错误处理?
欢迎来到PHP Smarty的世界。如果你在这里寻求如何调试和错误处理的方法,那么我可以向你保证,我们会让这个过程尽可能的有趣和轻松。 首先,让我们先来谈谈调试。在Smarty中,你可以使用以下几种方法来进行调试: 使用Sm…...
手搓vue3组件_0,打包配置
打包后引入项目是发现报错: Cannot read properties of null (reading isCE) TypeError: Cannot read properties of null (reading isCE)这个是由于vue版本冲突问题, 这里我引入了自己打包的ui组件库,但是ui组件库中打包进入了自己的vue,那么在此时使用时,如果你引入的自己的组…...
WebAssembly
WebAssembly(简称Wasm)是一种面向Web的二进制指令格式,用于在现代Web浏览器中运行高性能的可移植代码。它是一种跨平台、低级别的虚拟机技术,允许开发者将不同编程语言的代码编译成Wasm格式,然后在Web浏览器中运行。 …...
TM4C123库函数学习(2)--- LED闪烁,滴答定时器精准延时
前言 (1)阅读本文之前,需要先看TM4C123库函数学习(1)— 点亮LEDTM4C123的ROM函数简介keil开发环境搭建篇。 (2)TM4C123是M4的内核,拥有一个24位向下计数的SysTick定时器。࿰…...
Linux: network: tcp: back-off技术
当一个包需要重传的时候,会使用 exponential back-off来计算下一次重传的时间。 这个back-off的使用还是相当的广泛:《Adaptive Backoff Synchronization Technique》https://dl.acm.org/doi/pdf/10.1145/74926.74970 The general idea of backoff has …...
36 | 银行贷款数据分析
本文将以银行贷款数据分析为主题,深入探讨如何运用数据科学的方法,揭示银行贷款领域的内在规律和趋势。通过对贷款数据的分析,我们能够洞察不同类型贷款的分布情况、贷款金额的变化趋势,以及借款人的特征和还款情况等关键信息。 通过运用Python编程语言及相关的数据分析工…...
计算机网络-物理层(二)- 传输方式
计算机网络-物理层(二)- 传输方式 串型传输与并行传输 串行传输:是指数据是一个比特一个比特依次发送的,因此在发送端和接收端之间,只需要一条数据传输线路即可 并行传输:是指一次发送n个比特而不是一个比特,因此发送…...
超强台风“杜苏芮”来袭!如何实现安全可靠的通信?
暴雨来袭 超强台风“杜苏芮”是2023年太平洋台风季第5个被命名的台风,在我国东南沿海地区造成了巨大的影响,在7月28日登录福建省晋江市时,“杜苏芮”中心附近最大风力15级,达到了超强台风的等级;福州市区、闽侯、莆田…...
内网隧道—HTTP\DNS\ICMP
本文仅限于安全研究和学习,用户承担因使用此工具而导致的所有法律和相关责任! 作者不承担任何法律和相关责任! HTTP隧道 Neo-reGeorg Neo-reGeorg 是一个旨在积极重构 reGeorg 的项目,目的是: 提高可用性࿰…...
QT mouseTracking
在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent,但是MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到。要想鼠标不按下时的移动也能捕捉到,需要setMouseTracking(true)。 如果鼠标跟踪失效(默认),…...
java操作mongdb【超详细】
Java操作 搭建 搭建 依赖 <!--mongodb--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>配置文件 spring:data:mongodb:host…...
JavaScript函数
什么是函数? 在 JavaScript 中,函数是一段被封装起来用于特定任务的可重复使用的代码块。 例如: function logger() {console.log(IT知识一享); }这样就创造了logger()函数,后续可以重复利用这个函数让它输出日志,后…...
RISC-V公测平台发布 · 使用YCSB测试SG2042上的MySQL性能
实验介绍: YCSB(全称为Yahoo! Cloud Serving Benchmark),该性能测试工具由Java语言编写(在之前的MC文章中也提到过这个,如果没看过的读者可以去看看之前MC那一期),主要用于云端或者…...
GPT-OSS-20B快速部署实战:从下载到对话的完整流程
GPT-OSS-20B快速部署实战:从下载到对话的完整流程 1. 引言:为什么选择GPT-OSS-20B? 在当今AI技术快速发展的时代,找到一个既强大又易于部署的开源大语言模型并非易事。GPT-OSS-20B作为OpenAI推出的重量级开放模型,凭…...
【deepin】通过x11vnc与xrdp实现Windows无缝远程控制deepin桌面
1. 为什么需要远程控制deepin桌面? 作为一个长期使用deepin系统的开发者,我经常遇到需要在Windows电脑上远程操作deepin桌面的场景。比如在家办公时想用Windows笔记本访问公司的deepin开发机,或者给使用deepin的朋友远程解决问题。传统的Tea…...
Hashcat在Mac上的完整安装与使用指南:从零开始破解ZIP密码
Hashcat在Mac上的完整安装与使用指南:从零开始破解ZIP密码 如果你曾经遇到过忘记ZIP压缩包密码的尴尬情况,或者对密码恢复技术感兴趣,那么Hashcat绝对是你需要掌握的工具。作为世界上最快的密码恢复工具之一,Hashcat支持多种算法和…...
从“听”到“看”:希尔伯特变换如何让机械故障诊断更精准?一个振动信号分析实战
从“听”到“看”:希尔伯特变换如何让机械故障诊断更精准?一个振动信号分析实战 当工厂里的关键设备突然发出异常声响,经验丰富的老师傅可能会竖起耳朵听几秒,然后准确判断:"轴承内圈有损伤"。这种神奇的&qu…...
MySQL语句执行深度剖析:从连接到执行的全过程滞
开发个什么Skill呢? 通过 Skill,我们可以将某些能力进行模块化封装,从而实现特定的工作流编排、专家领域知识沉淀以及各类工具的集成。 这里我打算来一次“套娃式”的实践:创建一个用于自动生成 Skill 的 Skill,一是用…...
吃灰安卓机变身 OpenClaw 服务器 — 完整手册纲
前言 在使用 kubectl get $KIND -o yaml 查看 k8s 资源时,输出结果中包含大量由集群自动生成的元数据(如 managedFields、resourceVersion、uid 等)。这些信息在实际复用 yaml 清单时需要手动清理,增加了额外的工作量。 使用 kube…...
用户遇到了Docker镜像拉取超时的问题。我需要提供故障排除和解决方案。
你遇到的 Client.Timeout exceeded while awaiting headers 错误,核心原因是网络连接不稳定。虽然你已经配置了加速器,但从报错看,问题很可能就出在这个加速器地址上。 ⚠️ 配置了镜像源,为何还会超时? 这其实是个很常…...
Python 3.12 Special Attribute - 08 - __module__
Python 3.12 Special Attribute - __module____module__ 是 Python 中一个重要的内置特殊属性,它存储了定义 类、函数、方法 的模块名称(字符串)。这个属性在序列化(如 pickle)、动态导入、调试以及框架设计中扮演着…...
PowerPaint-V1 Gradio快速部署:Docker镜像免配置开箱即用
PowerPaint-V1 Gradio快速部署:Docker镜像免配置开箱即用 想不想体验一下,用画笔在图片上随便一涂,就能让不想要的物体瞬间消失,或者让缺失的背景完美补全?今天要介绍的这个工具,就能让你轻松做到。 Powe…...
[AI/应用/MCP] MCP Server/Tool 开发指南腋
简介 langchain专门用于构建LLM大语言模型,其中提供了大量的prompt模板,和组件,通过chain(链)的方式将流程连接起来,操作简单,开发便捷。 环境配置 安装langchain框架 pip install langchain langchain-community 其中…...
