如何构建一个对象池并使用
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那一期),主要用于云端或者…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...