强制Tomcat处理的DataSource被急切地初始化

时间:2011-05-12 12:34:26

标签: java tomcat apache-commons-dbcp permgen

在Java Web应用程序中消除了几个与PermGen相关的问题之后,我已经达到了以下几点:

  • 该应用程序在Tomcat 6.0.32中运行,并使用Tomcat管理的DataSource
  • DataSource$TOMCAT_HOME/conf/context.xml
  • 中定义
  • 当应用程序启动时,它会查找DataSource并且仅在那时DataSource实例化;
  • 来自commons-dbcp的BasicDataSource实现加载GenericObjectPool类,后者又开始java.util.Timer
  • 计时器启动TimerThread这是一个GC根,并由Web应用程序类加载器加载。

计时器创建的堆栈跟踪

java.util.Timer.<init>(Timer.java:123)
org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.<clinit>(GenericObjectPool.java:268)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1172)
org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:114)
org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2163)
org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2159)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1383)
org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:855)
org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:774)
org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)

计时器显示为由webapp类加载器加载

GC Roots

我的第一个问题是要求Tomcat急切地初始化DataSource,从而将其固定在公共类加载器中,但我发现无法做到这一点。我当然愿意采用其他方法来解决这个问题(但JNDI绑定的资源需要保留)。

如何确保TimerThread已链接到网络应用类加载器?

1 个答案:

答案 0 :(得分:0)

我不确定我明白了: 您希望您的DataSource只加载一次吗? 将其作为GlobalNamingResource放在您的server.xml中。从context.xml中引用它在您的webapps中。 (有关详细信息,请参阅此处http://tomcat.apache.org/tomcat-5.5-doc/config/globalresources.html

您希望为一个webapp加载它:将它放在webapps上下文xml中。

tomcats context.xml旨在包含应为所有webapps加载一次的资源。 (所以有5个webapps会产生5个实例。)

如果这没有帮助,请发布您的tomcats和webapps上下文xml。