对象池(连接池):连接池参数、commons-pool2、 GenericObjectPool常用参数详解

为什么会有对象池

在实际的应用工程当中,存在一些被频繁使用的、创建或者销毁比较耗时、持有的资源也比较昂贵的一些对象。比如:数据库连接对象、线程对象。所以如果能够通过一种方式,把这类对象统一管理,让这类对象可以被循环利用的话,就可以减少很多系统开销(内存、CPU、IO等),极大的提升应用性能。

Apache Commons Pool

Apache Commons Pool就是一个对象池的框架,他提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。Apache Commons Pool是很多连接池实现的基础,比如DBCP连接池、Jedis连接池等。
Apache Commons Pool有个两个大版本,commons-pool和commons-pool2。commons-pool2是对commons-pool的重构,里面大部分核心逻辑实现都是完全重写的。我们所有的源码分析都是基于commons-pool2。

在commons-pool2中,对象池的核心接口叫做ObjectPool,他定义了对象池的应该实现的行为。

  • addObject方法:往池中添加一个对象。池子里的所有对象都是通过这个方法进来的。
  • borrowObject方法:从池中借走到一个对象。借走不等于删除。对象一直都属于池子,只是状态的变化。
  • returnObject方法:把对象归还给对象池。归还不等于添加。对象一直都属于池子,只是状态的变化。
  • invalidateObject:销毁一个对象。这个方法才会将对象从池子中删除,当然这其中最重要的就是释放对象本身持有的各种资源。
  • getNumIdle:返回对象池中有多少对象是空闲的,也就是能够被借走的对象的数量。
  • getNumActive:返回对象池中有对象对象是活跃的,也就是已经被借走的,在使用中的对象的数量。
  • clear:清理对象池。注意是清理不是清空,改方法要求的是,清理所有空闲对象,释放相关资源。
  • close:关闭对象池。这个方法可以达到清空的效果,清理所有对象以及相关资源。

在commons-pool2中,ObjectPool的核心实现类是GenericObjectPool。

在前面的文章中我已经解析过addObject、borrowObject、returnObject、invalidateObject方法的实现,对应链接地址:

通过以往的源码解析,本文来总结下GenericObjectPool常用参数的作用。

 GenericObjectPool常用参数详解

参数

类型(默认值)

描述

lifo

boolean(true)

空闲队列是否维持后进先出,默认为true。

如果为false,就维持先进先出特性。

fairness

boolean(false)

如果多个调用线程在等待获取对象,那么他们之间是否应该先到先得(公平),默认为false,也就是不维持先到先得的特性。

maxWaitMillis

long(-1)

对象池没有可用空闲对象的时候,调用方最长等待多长时间(毫秒)。默认值 -1,表示无限等待。

如果配置为1000,表示最长等待1秒。超过1秒,给调用方返回超时异常。

maxTotal

int(8)

对象池的最大容量。池里最多存放多少个对象

默认8。

maxIdle

int(8)

对象池中最多可以有多少个空闲对象。

当对象被归还的时候,如果池中空闲对象数量已经达到该值,那么被归还的对象直接被销毁,不需要再进入空闲对象列表。

默认8。

minIdle

int(0)

对象池中最少需要有几个空闲对象。

高负载的应用系统中,维持一定量的空闲对象可以减少对象频繁销毁、创建。减轻应用压力。

默认值为0,该值的有效范围n应该满足: 0 < n <= maxIdle

当异步的回收器线程回收完对象、或者调用方线程归还对象、以及销毁对象等操作后,都会重新检查并确保对象池中至少有minIdle个空闲对象。

timeBetweenEvictionRunsMillis

long(-1)

回收器线程多久执行一次空闲对象回收(轮询间隔时间,单位毫秒)。

默认-1,意味着不启动回收器线程。

只有设置一个大于0的数值,才会启动回收器线程,同时下面要介绍的三个参数才会生效。否则,即便下面三个参数都指定了有效值,那么也不会产生实际效果。

如果配置为60000,意味着1分钟执行一次空闲回收。

numTestsPerEvictionRun

int(3)

根据该值x可以推导出一个数值n,标识回收过程需要检查多少个空闲对象。

如果x>=0,那么n=x。

如果x<0,那么n=(空闲对象数量/x的绝对值)向上取整,假设空闲对象一共有10个,该值配置为-3,那么就意味着这次回收需要检查4个空闲对象。

softMinEvictableIdleTimeMillis

long(-1)

回收时间阈值

一个对象如果空闲时间超过了该值(毫秒),并且空闲对象的数量已经大于了minIdle时,就可以被回收器回收。

只有大于0的值,才被认为是一个有效值。默认值-1相当于Long.MAX_VALUE。

如果设置为120000,意味着如果一个对象空闲时间超过了2分钟,并且空闲对象数量大于minIdle,那么这个对象可以被回收。

minEvictableIdleTimeMillis

long(1000L * 60L * 30L)

回收时间阈值

一个对象如果空闲时间超过了该值,不care空闲对象数量,即使空闲对象的数量已经小于minIdle了,一样也会被回收器回收。

默认值是30分钟。只有大于0的值,才被认为是一个有效值。小于0的值相当于Long.MAX_VALUE。

如果设置为180000,意味着如果一个对象空闲时间超过了3分钟,就可以被回收。

如果配置了minEvictableIdleTimeMillis,那么softMinEvictableIdleTimeMillis一定要小于minEvictableIdleTimeMillis才有意义,否则softMinEvictableIdleTimeMillis就相当于不生效。

testOnCreate

boolean(false)

当往对象池里新加入一个新对象的时候,是否校验该新对象的有效性。

默认false,也就是不校验。

这个一般不建议设置为true,新建的对象,在很短的时间内失效的可能性很小。

testOnBorrow

boolean(false)

当从对象池里借走一个对象的时候,是否校验该对象的有效性。

默认false,也就是不校验。

如果负载不是很高的系统,回收器轮询间隔又比较长的,该值可以设置为true,来保证获取到的连接一定是有效的。

testOnReturn

boolean(false)

当往对象池里归还一个对象的时候,是否校验该对象的有效性。

默认值为false。

这个一般不建议设置为true,归还的对象校验有效性的意义不是很大,还会降低性能。重点保证获取到的对象是有效的就行。参见:testOnBorrow

testWhileIdle

boolean(false)

当回收器在扫描空闲对象时,是否校验对象的有效性。

如果某个对象空闲时间还没达到规定的阈值,如果testWhileIdle配置为true,那么就会检查该对象是否还有效,如果该对象的资源已经失效(例如:连接断开),那么他就可以被回收。

这个强烈建议设置为true。(要与回收器轮询间隔时间、检测的对象数量配合好)。

例如:在某个高负载的系统里,对象频繁被借出、被归还。

1、testOnBorrow、testOnReturn都设置为false,提升性能;

2、timeBetweenEvictionRunsMillis设置为60000,一分钟进行一次空闲对象的回收检查。

3、numTestsPerEvictionRun设置为-1,检查所有空闲对象。

4、minEvictableIdleTimeMillis设置为180000,空闲超过3分钟的可以被回收。

5、testWhileIdle设置为true,不管空闲时间是否超时,每个空闲对象都检查下有效性,无效的一样被回收。

通过异步的回收器来尽可能的保证空闲对象的有效性,减少同步调用时有效性检查导致的响应延迟、以及有效性检查对底层带来的访问压力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值