对象池对象回收

问题描述:在实现对象池的时候都会面对一个回收的问题,大部分实现都是将回收的主动权交给了使用方,由使用方去触发对象的回收,这样就会触发这样一个问题,当使用方忘记去触发这样的行为,或是在使用的过程中长期的占有该对象却很少使用,这样就会降低对象池的使用效率。

这几天没事,就这个问题,思考了一些方法来解决这个问题,下面就谈谈我的一些想法,并且将主要的功能也实现了,现在就是在测试中。

         方案:在编写对象池的过程中,可以提供这样三种回收机制:

1.       被动回收,即回收还是由使用方发出

2.       自动回收,对象池能够在jvm进行gc的过程中,自动将分发出去的对象且已经没有引用到的,但是却没有回收回来的对象,自动的回收

3.       强制回收,定期或当对象池的对象使用完之后,池自动的对分发出去的对象进行描述,根据最近最少使用的原则回收对象,当使用方再次使用已经回收回来的对象的时候,在进行一次重新分配的过程,这样就可以提高整个池的使用率

这是我想到的关于提高池的使用率的方案。下面大概说下我是如何来实现的,由于代码只是初期的构想,所以很多点都考虑不是很全。

 

大概的类图如下:

 

 

ExecutorPools就是一个对象池,可以将任何对象放入这个池中进行重复使用,BeanFactory的功能就是用于初始化具体的池对象,从对象池中获取的对象,都会进行重新的包装,统一返回PoolObject,在由这个对象去获取具体的业务对象;RecoverTimer会定期的对分配出去的对象进行最近最少使用的检查(可以设置一个时间段)来强制回收分配出去的对象,而AutoRecoverThread会根据gc的频率去自动的回收那些分配出去但是没有回收且没有被引用的对象。

 

下面就具体讲下每个类中关键点是如何去实现的。

 

ExecutorPools:有两个map对象,主要用于记录已经分配出去的对象

       ConcurrentHashMap<WeakReference<Integer>, T> map,用于自动回收

ConcurrentHashMap<WeakReference<Integer>,PoolObject<T>> activeObjects,用于强制回收

这两个mapkey都是弱引用类型。

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.  返回具体的业务对象

上面就是一个大概的实现思路,当然这里面还有其他一些问题和一些我没有想到的问题,比如PoolObjectgetPoolObject方法获取具体的业务对象,如果使用方那边保留了具体业务对象的引用,这套机制就没有办法跑起来,所以使用方在使用的过程中不能保留有具体的业务对象的引用,由于这个池是一个泛型实现的所以针对这个问题到现在还没有想到好的解决办法。

当然,这是一个思路,里面有很多不足和没有想到的点,虽然我写了个简单的实现,但现在还在测试中。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值