问题描述:在实现对象池的时候都会面对一个回收的问题,大部分实现都是将回收的主动权交给了使用方,由使用方去触发对象的回收,这样就会触发这样一个问题,当使用方忘记去触发这样的行为,或是在使用的过程中长期的占有该对象却很少使用,这样就会降低对象池的使用效率。
这几天没事,就这个问题,思考了一些方法来解决这个问题,下面就谈谈我的一些想法,并且将主要的功能也实现了,现在就是在测试中。
方案:在编写对象池的过程中,可以提供这样三种回收机制:
1. 被动回收,即回收还是由使用方发出
2. 自动回收,对象池能够在jvm进行gc的过程中,自动将分发出去的对象且已经没有引用到的,但是却没有回收回来的对象,自动的回收
3. 强制回收,定期或当对象池的对象使用完之后,池自动的对分发出去的对象进行描述,根据最近最少使用的原则回收对象,当使用方再次使用已经回收回来的对象的时候,在进行一次重新分配的过程,这样就可以提高整个池的使用率
这是我想到的关于提高池的使用率的方案。下面大概说下我是如何来实现的,由于代码只是初期的构想,所以很多点都考虑不是很全。
大概的类图如下:
ExecutorPools就是一个对象池,可以将任何对象放入这个池中进行重复使用,BeanFactory的功能就是用于初始化具体的池对象,从对象池中获取的对象,都会进行重新的包装,统一返回PoolObject,在由这个对象去获取具体的业务对象;RecoverTimer会定期的对分配出去的对象进行最近最少使用的检查(可以设置一个时间段)来强制回收分配出去的对象,而AutoRecoverThread会根据gc的频率去自动的回收那些分配出去但是没有回收且没有被引用的对象。
下面就具体讲下每个类中关键点是如何去实现的。
ExecutorPools:有两个map对象,主要用于记录已经分配出去的对象
ConcurrentHashMap<WeakReference<Integer>, T> map,用于自动回收
ConcurrentHashMap<WeakReference<Integer>,PoolObject<T>> activeObjects,用于强制回收
这两个map的key都是弱引用类型。
PoolObject<T> getPoolObject()这个方法就是暴露给外界进行池对象获取的接口,在使用方请求池对象的时候,会进行如下的处理:
1. 会从对象池中获取对象
2. 根据池对象的hashCode,生成一个WeakReference<Integer>对象,并且关联到ReferenceQueue,这样在jvm进行gc的时候,就可以跟踪到池对象是否有被引用到
3. 将具体的池对象和弱引用封装为PoolObject对象,同时在两个map中进行注册,同时PoolObject中会保持弱引用对象的一个强引用,这样可以避免池对象在使用的时候被gc回收了,但是当没有PoolObject的引用的时候,jvm进行gc的时候就会自动回收这个弱引用,这样就可以通过ReferenceQueue进行跟踪,同时自动回收分配出去的对象
4. 返回PoolObject
Map的使用,后台启动一个线程,check RefeQueue中是否有对象被回收了,如果检查到了,就会从map中将已经分配出去的对象重新放入池中供继续使用。
ActiveObject的使用,当没有对象可以分配或过了指定时间段,就会去遍历ActiveObject中的对象最近使用的时间点,用当前的时间减去最近使用的时间点,如果超过设定的使用时间间隔就会将该对象回收到对象池中,同时将PoolObject的状态设置为不可使用,这样使用方虽然有这个对象的引用,但是在使用的时候会重新请求分配对象。
PoolObject,这个类主要是对具体的业务对象和弱引用进行封装,一方面可以提供一个统一的接口使对象池可以适合任何对象,另一方面通过对弱引用进行强引用,可以实现进行自动回收的功能。这个类的主要方法是T getPoolObject(),获取具体的业务对象:
1. 检查active状态,确定该对象是否可用,可用到3,不可用2
2. 请求分配新的对象,根据分配到的对象,激活当前对象
3. 更新最近使用时间,
4. 返回具体的业务对象
上面就是一个大概的实现思路,当然这里面还有其他一些问题和一些我没有想到的问题,比如PoolObject的getPoolObject方法获取具体的业务对象,如果使用方那边保留了具体业务对象的引用,这套机制就没有办法跑起来,所以使用方在使用的过程中不能保留有具体的业务对象的引用,由于这个池是一个泛型实现的所以针对这个问题到现在还没有想到好的解决办法。
当然,这是一个思路,里面有很多不足和没有想到的点,虽然我写了个简单的实现,但现在还在测试中。
- 大小: 20.6 KB
分享到:
相关推荐
1. **对象创建与回收**:DeePool提供API用于创建特定类型的对象池,并负责对象的创建、分配和回收。 2. **自动扩展**:当对象池中的对象被耗尽时,DeePool能自动扩展池的大小,避免因对象不足而影响程序运行。 3. **...
利用接口特性构建可自动回收的Query对象池 构建一个线程池,外部通过指定接口调用线程中的Query处理数据库操作,当外部使用完成后,依据接口生存期自管理的特性释放外部的引用; 特性: 1. 线程内查询,外部调用...
在计算机科学和编程领域,对象池是一种内存管理策略,它预先创建并维护一组对象,以供重复使用,而不是每次需要时都创建新对象。这种方式可以显著提高程序性能,特别是对于那些生命周期短暂但创建成本较高的对象。...
### Java对象池技术的原理及其实现 #### 摘要 本文深入探讨了Java对象池技术的基本原理及其实现方式,旨在帮助读者理解如何利用对象池优化Java应用程序的性能。通过对对象池技术核心概念——缓存与共享的阐述,本文...
- 回收对象:当子弹完成任务后,将其放回对象池,而不是销毁。 2. 实现Bullet类 子弹对象需要继承自Unity的GameObject或其他基础类,并包含必要的行为和状态管理。例如,它可能包含一个Update()方法来更新子弹的...
Delphi多线程DB组件接口特性创建可自动回收的Query对象池,通过指定接口调用线程中的Query处理数据库操作,当请求结束后自动释放外部引用; 简要说明: TParamItem 管理存储过程的参数; ...
### 对象池技术详解 #### 一、对象池的基本概念 在软件开发中,特别是针对高性能、高并发的应用场景,对象池技术是一种非常实用的设计模式。它主要用于避免频繁创建和销毁对象所带来的性能开销,特别是在对象创建...
对象池在计算机科学,尤其是游戏开发领域,是一个重要的设计模式,它主要应用于管理频繁创建和销毁的对象,以提高性能和优化资源使用。Unity引擎中,对象池被广泛应用于游戏对象的生命周期管理,如敌人、子弹或者...
5. **对象回收**:当对象不再需要时,将其设为不可见或非活动状态,然后返回到池中,而不是销毁。 在"ObjectPool"这个示例中,我们可以预期包含以下关键部分: - 一个名为`ObjectPoolManager`的C#脚本,作为对象池...
"对象池"是一种常见的性能优化策略,它针对的是频繁创建和销毁对象所导致的性能损失。本文将深入探讨对象池的概念、工作原理以及在实际应用中的优势和注意事项。 对象池的基本思想是预先创建并维护一组对象,而不是...
这个实现可能包括类定义、对象池的初始化函数、对象的分配和回收方法,以及可能的扩展和收缩池大小的逻辑。通过对这些代码的阅读和分析,可以更深入地理解对象池的工作原理以及如何在实际项目中应用。 对象池在游戏...
3. **对象回收**:当对象不再需要时,而不是立即销毁,它会被返回到对象池中,变为非活动状态,等待下一次复用。 4. **动态扩展**:优秀的对象池插件还支持在运行时动态扩展和收缩,根据游戏需求自动增加或减少对象...
4. **对象回收**:定期检查池中的对象,若发现已失效或不可用的对象,及时释放资源并重新创建。 5. **池大小动态调整**:根据实际运行情况动态调整池的大小,以适应不同负载需求。 总结来说,Java对象池是一种优化...
4. **对象池管理**:维护对象池的使用情况,确保子弹在使用和未使用之间正确切换,并且在适当的时候进行对象的回收和清理。 5. **代码注释**:为了帮助理解,Demo案例中的代码会有详细的注释,解释每个步骤的作用和...
对象池是一种在软件设计中常见的优化技术,主要目的是提高程序性能和减少系统资源的...通过使用对象池,可以显著减少系统资源的分配和回收开销,提高程序运行效率。理解并熟练应用对象池技术对于提升系统性能至关重要。
对象池是一种在软件开发中用于优化资源管理的技术,它的核心思想是预先创建并维护一组对象,以便在需要时快速分配,而不是每次都新建对象。这种方式可以减少频繁创建和销毁对象带来的性能开销,尤其是在处理大量短...
总结来说,C#实现的万能对象池是通过泛型和面向对象的设计来提供一种通用的资源管理机制,优化了对象生命周期的管理,减少了垃圾回收的频率,提升了程序运行效率。在实际项目中,根据需求对对象池进行适当的定制和...
标题中的“对象池工厂(微型IOC容器)”是一个关于软件设计模式和轻量级依赖注入框架的概念。对象池是一种优化技术,用于管理对特定类型对象的创建和复用,以提高性能,减少系统资源的消耗。它通过维护一个对象集合来...
Apache对象池技术是一种高效利用资源的策略,它通过预先创建并维护一组可重用对象来减少频繁创建和销毁对象带来的开销。在Java环境中,Apache Commons Pool库是实现对象池的常见工具,它提供了多种对象池实现,适用...
对于对象池的优化逻辑其实是见仁见智的,并不是随随便便就拿来用,其实很多时候我们并不需要通过对象池来处理,通过对象池的主要目的是: 防止对象被频繁的创建和删除,从而内存抖动、频繁GC(垃圾回收)对象初始化...