- 浏览: 76565 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
天然呆的爱死你了呢:
解释的很好
<mvc:annotation-driven />注解意义 -
jiaqian0118:
无权访问?
很好的互联网研发资源 -
dzwillpower:
location = (JSONObject) locatio ...
Android开发:通过Wifi获取经纬度
以下图片来源于http://commons.apache.org/pool/guide/sequencediagrams.html,加了点注释而已 所有的时间都是毫秒,并且 GenericObjectPool 是 thread safe,以下分别说明各个参数: whenExhaustedAction maxWait lifo testOnBorrow maxIdle 默认值为 DEFAULT_MAX_IDLE=8,超过该值的 idle 对象会被destory 基本上看到这里就能用了,最好别用 evictor,除非要求..... 例如 db长连接、心跳 minIdle numTestsPerEvictionRun minEvictableIdleTimeMillis softMinEvictableIdleTimeMillis 备注1,minEvictableIdleTimeMillis 和 minEvictableIdleTimeMillis 的使用方法
创建新的对象并初始化的操作,可能会消耗很多的时间。在这种对象的初始化工作包含了一些费时的操作(例如,从一台位于20,000千米以外的主机上读出一些数据)的时候,尤其是这样。在需要大量生成这样的对象的时候,就可能会对性能造成一些不可忽略的影响。要缓解这个问题,除了选用更好的硬件和更棒的虚拟机以外,适当地采用一些能够减少对象创建次数的编码技巧,也是一种有效的对策。对象池化技术(Object Pooling)就是这方面的著名技巧,而Jakarta Commons Pool组件则是处理对象池化的得力外援。 对象池化的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。 对于没有状态的对象(例如String),在重复使用之前,无需进行任何处理;对于有状态的对象(例如StringBuffer),在重复使用之前,就需要把它们恢复到等同于刚刚生成时的状态。由于条件的限制,恢复某个对象的状态的操作不可能实现了的话,就得把这个对象抛弃,改用新创建的实例了。 并非所有对象都适合拿来池化――因为维护对象池也要造成一定开销。对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况。但是对于生成时开销可观的对象,池化技术就是提高性能的有效策略了。 说明:英语中的Pool除了“池”之外,还有“供多方共享的资源”意思。作者十分怀疑第二种才是“Object Pool”中的Pool的实际含义,但是“对象池”的说法已经广为流传,而一时又没有足以替代的贴切译法,因此这里仍然沿用这种译名。 Jakarta Commons Pool是一个用于在Java程序中实现对象池化的组件。它的基本情况是: 为了顺利的按照本文中提到的方法使用Pool组件,除去Java 2 SDK外,还需要先准备下列一些东西: 以上两种软件均有已编译包和源代码包两种形式可供选择。一般情况下,使用已编译包即可。不过建议同时也下载源代码包,作为参考资料使用。 如果打算使用源代码包自行编译,那么还需要准备以下一些东西: 具体的编译方法,可以参看有关的Ant文档。 将解压或编译后得到的commons-pool.jar和commons-collections.jar放入CLASSPATH,就可以开始使用Pool组件了。 PoolableObjectFactory、ObjectPool和ObjectPoolFactory 在Pool组件中,对象池化的工作被划分给了三类对象: 相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。 Pool组件利用PoolableObjectFactory来照看被池化的对象。ObjectPool的实例在需要处理被池化的对象的产生、激活、挂起、校验和销毁工作时,就会调用跟它关联在一起的PoolableObjectFactory实例的相应方法来操作。 PoolableObjectFactory是在org.apache.commons.pool包中定义的一个接口。实际使用的时候需要利用这个接口的一个具体实现。Pool组件本身没有包含任何一种PoolableObjectFactory实现,需要根据情况自行创立。 创立PoolableObjectFactory的大体步骤是: 最后完成的PoolableObjectFactory类似这个样子: 有了合适的PoolableObjectFactory之后,便可以开始请出ObjectPool来与之同台演出了。 ObjectPool是在org.apache.commons.pool包中定义的一个接口,实际使用的时候也需要利用这个接口的一个具体实现。Pool组件本身包含了若干种现成的ObjectPool实现,可以直接利用。如果都不合用,也可以根据情况自行创建。具体的创建方法,可以参看Pool组件的文档和源码。 ObjectPool的使用方法类似这样: 这些操作都可能会抛出异常,需要另外处理。 比较完整的使用ObjectPool的全过程,可以参考这段代码: 另外,ObjectPool接口还定义了几个可以由具体的实现决定要不要支持的操作,包括: void clear() 清除所有当前在此对象池中休眠的对象。 int getNumActive() 返回已经从此对象池中借出的对象的总数。 int getNumIdle() 返回当前在此对象池中休眠的对象的数目。 void setFactory(PoolableObjectFactory factory) 将当前对象池与参数中给定的PoolableObjectFactory相关联。如果在当前状态下,无法完成这一操作,会有一个IllegalStateException异常抛出。 有时候,要在多处生成类型和设置都相同的ObjectPool。如果在每个地方都重写一次调用相应构造方法的代码,不但比较麻烦,而且日后修改起来,也有所不便。这种时候,正是使用ObjectPoolFactory的时机。 ObjectPoolFactory是一个在org.apache.commons.pool中定义的接口,它定义了一个称为ObjectPool createPool()方法,可以用于大量生产类型和设置都相同的ObjectPool。 Pool组件中,对每一个ObjectPool实现,都有一个对应的ObjectPoolFactory实现。它们相互之间,有一一对应的参数相同的构造方法。使用的时候,只要先用想要的参数和想用的ObjectPoolFactory实例,构造出一个ObjectPoolFactory对象,然后在需要生成ObjectPool的地方,调用这个对象的createPool()方法就可以了。日后无论想要调整所用ObjectPool的参数还是类型,只需要修改这一处,就可以大功告成了。 将 《使用ObjectPool》一节中的例子,改为使用ObjectPoolFactory来生成所用的ObjectPool对象之后,基本就是这种形式: PoolableObjectFactory定义了许多方法,可以适应多种不同的情况。但是,在并没有什么特殊需要的时候,直接实现PoolableObjectFactory接口,就要编写若干的不进行任何操作,或是始终返回true的方法来让编译通过,比较繁琐。这种时候就可以借助BasePoolableObjectFactory的威力,来简化编码的工作。 BasePoolableObjectFactory是org.apache.commons.pool包中的一个抽象类。它实现了PoolableObjectFactory接口,并且为除了makeObject之外的方法提供了一个基本的实现――activateObject、passivateObject和destroyObject不进行任何操作,而validateObject始终返回true。通过继承这个类,而不是直接实现PoolableObjectFactory接口,就可以免去编写一些只起到让编译通过的作用的代码的麻烦了。 这个例子展示了一个从BasePoolableObjectFactory扩展而来的PoolableObjectFactory: 可口可乐公司的软饮料有可口可乐、雪碧和芬达等品种,百事可乐公司的软饮料有百事可乐、七喜和美年达等类型,而Pool组件提供的ObjectPool实现则有StackObjectPool、SoftReferenceObjectPool和GenericObjectPool等种类。 不同类型的软饮料各有各自的特点,分别适应不同消费者的口味;而不同类型的ObjectPool也各有各自的特色,分别适应不同的情况。 StackObjectPool利用一个java.util.Stack对象来保存对象池里的对象。这种对象池的特色是: StackObjectPool的构造方法共有六个,其中: 用不带factory参数的构造方法构造的StackObjectPool实例,必须要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。 这种对象池可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。 SoftReferenceObjectPool利用一个java.util.ArrayList对象来保存对象池里的对象。不过它并不在对象池里直接保存对象本身,而是保存它们的“软引用”(Soft Reference)。这种对象池的特色是: SoftReferenceObjectPool的构造方法共有三个,其中: 用不带factory参数的构造方法构造的SoftReferenceObjectPool实例,也要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。 这种对象池也可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。 GenericObjectPool利用一个org.apache.commons.collections.CursorableLinkedList对象来保存对象池里的对象。这种对象池的特色是:
WHEN_EXHAUSTED_BLOCK
参考 maxWait
WHEN_EXHAUSTED_FAIL
WHEN_EXHAUSTED_GROW
如果 whenExhaustedAction = WHEN_EXHAUSTED_BLOCK,那么 borrow 不能立即返回 Object时,
会wait,知道得到池化对象,或者超过 maxWait。如果maxWait < 1,那么 会一直等到获得池化对象
true/false
GenericObjectPool.borrowObject() 时 是否调用 PoolableObjectFactory.validateObject
testOnReturn
GenericObjectPool.returnObject() 时 是否调用 PoolableObjectFactory.validateObject
timeBetweenEvictionRunsMillis
启动evictor thread的间隔,如果设置为<1不会启动evictor thread
evictor thread 按照规则下面定义来 填充/移除 池中的对象
evictor thread 在执行检查时会阻塞 borrow/return,因此如果该参数设置的很小,会造成evictor thread频繁执行而影响性能
Eviction runs require an exclusive synchronization
lock on the pool, so if they run too frequently and / or incur excessive
latency when creating, destroying or validating object instances,
performance issues may result
如果evictor启动,evictor检查到池中的对象小于该值时,会创建min(minIdle, numActive + numIdle - maxActive) 的对象来填充池。小心使用该变量,设置为 <1最安全,可能导致dbcp死锁:dbcp-44,在common-pool 1.5 dbcp1.4中已经修正了这个问题,4年
如果evictor启动,evictor每次启动时会检查池中的 x 个对象
numTestsPerEvictionRun > 0, x = min(_numTestsPerEvictionRun, GenericObjectPool.getNumIdle())
numTestsPerEvictionRun < 0, x = ceil( GenericObjectPool.getNumIdle())/abs(numTestsPerEvictionRun) )
i.e. abs(numTestsPerEvictionRun) 分之一的空闲对象会被检查
如果evictor启动,evictor每次检查时可能会将池中空闲太久的对象移除池
如果设置为 < 1,是否把 idle 对象移除要看 softMinEvictableIdleTimeMillis
如果设置为 > 0,那么会把闲置了 minEvictableIdleTimeMillis 的对象PoolableObjectFactory.destroyObject掉
如果evictor启动,并且minEvictableIdleTimeMillis < 1 或者按照 minEvictableIdleTimeMillis 计算对象不需要移出池
如果设置为 < 1,则不会移除任何idle对象
如果设置为 > 0,则当对象闲置的时间超过softMinEvictableIdleTimeMillis 且 GenericObjectPool.getNumIdle > minIdle 时 将对象移除池
一般应该把minEvictableIdleTimeMillis 配置为 -1,把softMinEvictableIdleTimeMillis配置为整数
_testWhileIdle
如果evictor启动,该变量为true则调用 PoolableObjectFactory.validateObject
if ((getMinEvictableIdleTimeMillis() > 0) &&
(idleTimeMilis > getMinEvictableIdleTimeMillis())) {
removeObject = true;
} else if ((getSoftMinEvictableIdleTimeMillis() > 0) &&
(idleTimeMilis > getSoftMinEvictableIdleTimeMillis()) &&
((getNumIdle() + 1)> getMinIdle())) { // +1 accounts for object we are processing
removeObject = true;When to use sidebars
import org.apache.commons.pool.PoolableObjectFactory;
public class PoolableObjectFactorySample
implements PoolableObjectFactory {
private static int counter = 0;
}
public Object makeObject() throws Exception {
Object obj = String.valueOf(counter++);
System.err.println("Making Object " + obj);
return obj;
}
public void activateObject(Object obj) throws Exception {
System.err.println("Activating Object " + obj);
}
public void passivateObject(Object obj) throws Exception {
System.err.println("Passivating Object " + obj);
}
public boolean validateObject(Object obj) {
boolean result = (Math.random() > 0.5);
System.err.println("Validating Object "
+ obj + " : " + result);
return result;
}
public void destroyObject(Object obj) throws Exception {
System.err.println("Destroying Object " + obj);
}
PoolableObjectFactorySample.java
import org.apache.commons.pool.PoolableObjectFactory;
public class PoolableObjectFactorySample
implements PoolableObjectFactory {
private static int counter = 0;
public Object makeObject() throws Exception {
Object obj = String.valueOf(counter++);
System.err.println("Making Object " + obj);
return obj;
}
public void activateObject(Object obj) throws Exception {
System.err.println("Activating Object " + obj);
}
public void passivateObject(Object obj) throws Exception {
System.err.println("Passivating Object " + obj);
}
public boolean validateObject(Object obj) {
/* 以1/2的概率将对象判定为失效 */
boolean result = (Math.random() > 0.5);
System.err.println("Validating Object "
+ obj + " : " + result);
return result;
}
public void destroyObject(Object obj) throws Exception {
System.err.println("Destroying Object " + obj);
}
}
PoolableObjectFactory factory = new PoolableObjectFactorySample();
ObjectPool pool = new StackObjectPool(factory);
Object obj = null;
obj = pool.borrowObject();
pool.returnObject(obj);
pool.close();
ObjectPoolSample.java
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.StackObjectPool;
public class ObjectPoolSample {
public static void main(String[] args) {
Object obj = null;
PoolableObjectFactory factory
= new PoolableObjectFactorySample();
ObjectPool pool = new StackObjectPool(factory);
try {
for(long i = 0; i < 100 ; i++) {
System.out.println("== " + i + " ==");
obj = pool.borrowObject();
System.out.println(obj);
pool.returnObject(obj);
}
obj = null;//明确地设为null,作为对象已归还的标志
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try{
if (obj != null) {//避免将一个对象归还两次
pool.returnObject(obj);
}
pool.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
ObjectPoolFactorySample.java
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.ObjectPoolFactory;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.StackObjectPoolFactory;
public class ObjectPoolFactorySample {
public static void main(String[] args) {
Object obj = null;
PoolableObjectFactory factory
= new PoolableObjectFactorySample();
ObjectPoolFactory poolFactory
= new StackObjectPoolFactory(factory);
ObjectPool pool = poolFactory.createPool();
try {
for(long i = 0; i < 100 ; i++) {
System.out.println("== " + i + " ==");
obj = pool.borrowObject();
System.out.println(obj);
pool.returnObject(obj);
}
obj = null;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try{
if (obj != null) {
pool.returnObject(obj);
}
pool.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
BasePoolableObjectFactorySample.java
import org.apache.commons.pool.BasePoolableObjectFactory;
public class BasePoolableObjectFactorySample
extends BasePoolableObjectFactory {
private int counter = 0;
public Object makeObject() throws Exception {
return String.valueOf(counter++);
}
}
发表评论
-
Java 8简明教程
2014-03-24 09:30 626“Java并没有没落,人们很快就会发现这一点” 欢迎阅读我 ... -
Java身份证验证方法
2012-05-10 15:36 926package com.tg.user.controller; ... -
Linux 内存清理
2011-06-15 16:08 970在 kernel 2.6.16 以上可使用: echo ... -
走进Java 7中的模块系统
2011-04-15 11:59 787笔者在观看过Devoxx关于Jigsaw的一段演示后,我 ... -
20个开发人员非常有用的Java功能代码
2011-04-15 11:58 10061. 把Strings转换成int和把int转换成String ... -
Java程序性能优化之找出内存溢出元凶
2011-04-15 11:55 944我曾经在刚入行的时候做过一个小的swing程序,用到了java ... -
Java内存溢出的详细解决方案
2011-04-15 11:52 738一、内存溢出类型 1、java.lang.OutOfMemo ...
相关推荐
Java对象池化技术是一种优化程序性能的策略,它通过预先创建一组对象并保留它们,以便在需要时重复使用,而不是每次需要时都创建新的对象。这样可以显著减少对象的创建和初始化时间,尤其适用于那些创建成本较高的...
互联网资讯,技术简介,IT、AI技术,人工智能
Java Socket 连接池实现是提高网络应用性能和效率的关键技术之一。在高并发的网络环境中,频繁地创建和销毁Socket连接会导致大量的系统资源浪费,影响整体性能。为了解决这个问题,开发人员通常会使用连接池来管理和...
1.高效简单池化的HttpClient工具类,提供单元测试用列。 2.支持基于SpringBoot 2.1.x的自动装载模块,引用依赖即可使用。 3.公司几十个项目都使用该工具类访问第三方的Http/Https+json协议接口。 4.经过上市公司多个...
/** * 初始化连接池中数据库连接个数 * */ private void initConnections(){ for(int i=0;i;i++){ try { Connection conn=createConnection();... DatabaseMetaData metaData=conn.getMetaData();...
标题"commons-dbcp"表明我们讨论的是Apache Commons DBCP库,这是一个用于管理数据库连接的Java池化解决方案。这个库包含了处理数据库连接池的类和接口,使得开发者可以轻松地在应用中集成数据库连接池功能。 描述...
该项目是一个基于Java核心的GPU池化系统,旨在打造一体化AI训练与推理平台。源码包含978个文件,涵盖169个Python脚本、152个Java源文件、145个YAML配置文件以及多种其他类型文件。该系统支持多机多卡训练环境,优化...
java线程池是指一种池化技术,用于管理和复用线程,以提高系统的性能和可靠性。线程池可以帮助开发者更好地管理线程资源,避免线程的频繁创建和销毁,从而提高系统的性能和可靠性。 在使用java线程池时,通常有两种...
使用过Elasticsearch RestFul API的都知道,在Java端使用是ES服务需要创建Java Client,但是每一次连接都实例化一个client,对系统的消耗很大,而且最令人头疼的是它的连接非常慢。所以为了解决上述问题并提高client...
通过DataSource,可以实现数据库连接的池化,提高性能和资源利用率。 6. **权限控制**:在办公自动化系统中,权限控制至关重要,确保不同用户只能访问其授权的资源。这通常通过认证(Authentication)和授权...
- 对象池化策略优化,确保内存资源的有效利用。 - 整体性能调优,通过减小不必要的内存消耗来提高程序的响应速度。 在实际应用中,理解对象的内存占用并不仅仅是为了追求最小的内存消耗,更重要的是找到性能和资源...
1. **连接管理**:该驱动程序支持多种连接模式,如单线程、多线程和池化连接。MongoClient类是主要的入口点,用于创建到MongoDB服务器的连接。 2. ** CRUD操作**:CRUD代表创建(Create)、读取(Read)、更新(Update)...
3. **卷积神经网络(Convolutional Neural Networks, CNN)**:重点讨论用于图像处理的网络结构,如卷积层、池化层和全连接层的设计与实现。 4. **循环神经网络(Recurrent Neural Networks, RNN)**:介绍处理序列...
- **网络架构**:定义YOLO模型的网络结构,包括卷积层、池化层、全连接层等,可以用深度学习库如DeepJava Library或Deeplearning4j实现。 - **损失函数和优化器**:在训练模型时,需要定义损失函数(如交叉熵)和...
Sphinx 搜索 Java API 包装器,用于池化 sphinx 搜索连接。 基本用法 连接池由PooledSphinxDataSource类处理。 配置完成后,您可以通过调用getSphinxClient()方法从数据源获取 sphinx 搜索客户端的实例。 请注意,...
- 避免大对象的创建:尽量减少大对象的使用,或者考虑使用流式操作、池化对象等技术。 - 检查并消除内存泄漏:使用内存分析工具(如VisualVM、MAT等)查找并修复内存泄漏。 - 使用弱引用和软引用:对于不需要长期...
2. Commons-pool-1.6.jar: 这是Apache Commons Pool库的一个版本,主要用于对象池化。在Java中,为了提高性能和减少资源消耗,通常会使用对象池来管理Jedis实例。Apache Commons Pool提供了一个通用的对象池服务,...
这样的模型通常包含卷积层来提取特征,池化层来减小数据尺寸,全连接层来进行分类,最后是softmax层来输出字符概率。 在实现过程中,数据集的准备至关重要。需要收集大量的带标签的车牌图像,包括不同角度、光照...
### Apache Commons Pool:Java对象池化技术详解 #### 一、引言 在现代软件开发过程中,尤其是在基于Java的企业级应用开发中,资源管理和优化变得尤为重要。创建和销毁对象的成本通常较高,特别是在高并发场景下,...