当前位置: 首页 > news >正文

如何构建一个对象池并使用

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.背景 在项目中&#xff0c;如果频繁的通过new 创建对象&#xff0c;之后让gc再去回收&#xff0c;这就很容易造成内存抖动&#xff0c;并且频繁的GC本身也会消耗内存&#xff0c;这样就很容易在一瞬间造成OOM 内存溢出&#xff0c;因为瞬间申请大量内存会造成内存占用突然升…...

【沁恒蓝牙mesh】CH58x USB功能开发记录(三)

本博文主要记录 &#xff0c;【沁恒蓝牙mesh】CH58x USB功能开发记录&#xff08;三&#xff09;&#xff0c;数据收发基于寄存器级别解释 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x1f60e;&#x1f4dd; 个人主页&#xf…...

2023国赛数学建模D题思路分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…...

linux 学习————LNMP之分布式部署

目录 一、概述 二、LNMP环境部署 三、配置nginx 四、 配置php使nginx能够解析.php 五、配置mysql 六、配置discuz进行登录论坛访问测试 一、概述 LNMP代表 Linux、Nginx、MySQL、PHP&#xff0c;是一种常用的服务器架构。它由以下组件组成&#xff1a; Linux&#xff1a;作…...

第八课 双重所有格和不定代词

系列文章目录 文章目录 系列文章目录前言一、of s 的所有格1、of 有生命的名词 ’s2、of 名词性物主代词3、小结 二、反身代词1、作宾语和介词宾语2、作表语3、作固定惯语 三、相互代词四、指示代词 Such 和 Same 的用法 前言 一、of s 的所有格 1、of 有生命的名词 ’s 2、…...

使用xrdp协议远程桌面控制树莓派,无需公网IP!

远程桌面控制树莓派&#xff0c;我们可以用xrdp协议来实现&#xff0c;它内部使用的是windows远程桌面的协议。我们只需要在树莓派上安装xrdp&#xff0c;就可以在同个局域网下远程桌面控制树莓派。 而如果需要在公网下远程桌面控制树莓派&#xff0c;可以通过cpolar内网穿透&…...

数据结构【图的类型定义和存储结构】

数据结构之图 图的定义和概念图的定义图的术语 图的类型定义图的存储结构数组&#xff08;邻接矩阵&#xff09;表示法无向图的邻接矩阵表示法有向图的邻接矩阵表示法网&#xff08;即有权图&#xff09;的邻接矩阵表示法 邻接矩阵的ADT定义邻接表&#xff08;链式&#xff09;…...

PHP Smarty如何进行调试和错误处理?

欢迎来到PHP Smarty的世界。如果你在这里寻求如何调试和错误处理的方法&#xff0c;那么我可以向你保证&#xff0c;我们会让这个过程尽可能的有趣和轻松。 首先&#xff0c;让我们先来谈谈调试。在Smarty中&#xff0c;你可以使用以下几种方法来进行调试&#xff1a; 使用Sm…...

手搓vue3组件_0,打包配置

打包后引入项目是发现报错: Cannot read properties of null (reading isCE) TypeError: Cannot read properties of null (reading isCE)这个是由于vue版本冲突问题, 这里我引入了自己打包的ui组件库,但是ui组件库中打包进入了自己的vue,那么在此时使用时,如果你引入的自己的组…...

WebAssembly

WebAssembly&#xff08;简称Wasm&#xff09;是一种面向Web的二进制指令格式&#xff0c;用于在现代Web浏览器中运行高性能的可移植代码。它是一种跨平台、低级别的虚拟机技术&#xff0c;允许开发者将不同编程语言的代码编译成Wasm格式&#xff0c;然后在Web浏览器中运行。 …...

TM4C123库函数学习(2)--- LED闪烁,滴答定时器精准延时

前言 &#xff08;1&#xff09;阅读本文之前&#xff0c;需要先看TM4C123库函数学习&#xff08;1&#xff09;— 点亮LEDTM4C123的ROM函数简介keil开发环境搭建篇。 &#xff08;2&#xff09;TM4C123是M4的内核&#xff0c;拥有一个24位向下计数的SysTick定时器。&#xff0…...

Linux: network: tcp: back-off技术

当一个包需要重传的时候&#xff0c;会使用 exponential back-off来计算下一次重传的时间。 这个back-off的使用还是相当的广泛&#xff1a;《Adaptive Backoff Synchronization Technique》https://dl.acm.org/doi/pdf/10.1145/74926.74970 The general idea of backoff has …...

36 | 银行贷款数据分析

本文将以银行贷款数据分析为主题,深入探讨如何运用数据科学的方法,揭示银行贷款领域的内在规律和趋势。通过对贷款数据的分析,我们能够洞察不同类型贷款的分布情况、贷款金额的变化趋势,以及借款人的特征和还款情况等关键信息。 通过运用Python编程语言及相关的数据分析工…...

计算机网络-物理层(二)- 传输方式

计算机网络-物理层&#xff08;二&#xff09;- 传输方式 串型传输与并行传输 串行传输:是指数据是一个比特一个比特依次发送的&#xff0c;因此在发送端和接收端之间&#xff0c;只需要一条数据传输线路即可 并行传输:是指一次发送n个比特而不是一个比特&#xff0c;因此发送…...

超强台风“杜苏芮”来袭!如何实现安全可靠的通信?

暴雨来袭 超强台风“杜苏芮”是2023年太平洋台风季第5个被命名的台风&#xff0c;在我国东南沿海地区造成了巨大的影响&#xff0c;在7月28日登录福建省晋江市时&#xff0c;“杜苏芮”中心附近最大风力15级&#xff0c;达到了超强台风的等级&#xff1b;福州市区、闽侯、莆田…...

内网隧道—HTTP\DNS\ICMP

本文仅限于安全研究和学习&#xff0c;用户承担因使用此工具而导致的所有法律和相关责任&#xff01; 作者不承担任何法律和相关责任&#xff01; HTTP隧道 Neo-reGeorg Neo-reGeorg 是一个旨在积极重构 reGeorg 的项目&#xff0c;目的是&#xff1a; 提高可用性&#xff0…...

QT mouseTracking

在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent&#xff0c;但是MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到。要想鼠标不按下时的移动也能捕捉到&#xff0c;需要setMouseTracking(true)。 如果鼠标跟踪失效&#xff08;默认&#xff09;&#xff0c;…...

java操作mongdb【超详细】

Java操作 搭建 搭建 依赖 <!--mongodb--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>配置文件 spring:data:mongodb:host…...

JavaScript函数

什么是函数&#xff1f; 在 JavaScript 中&#xff0c;函数是一段被封装起来用于特定任务的可重复使用的代码块。 例如&#xff1a; function logger() {console.log(IT知识一享); }这样就创造了logger()函数&#xff0c;后续可以重复利用这个函数让它输出日志&#xff0c;后…...

RISC-V公测平台发布 · 使用YCSB测试SG2042上的MySQL性能

实验介绍&#xff1a; YCSB&#xff08;全称为Yahoo! Cloud Serving Benchmark&#xff09;&#xff0c;该性能测试工具由Java语言编写&#xff08;在之前的MC文章中也提到过这个&#xff0c;如果没看过的读者可以去看看之前MC那一期&#xff09;&#xff0c;主要用于云端或者…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;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…...