2012-10-29 41 views
0

我目前有一个Java EE应用程序,其中实现了我自己的连接池类。我使用的每个方法都执行一个简单的查询(Statement和ResultSet)。在我使用JDBC/my pool的每个方法的finally块中,首先关闭ResultSet,然后关闭Statement,尽可能多的书籍和在线指示应该完成的资源。最后,我将连接返回到池中。JDBC连接池内存问题(Java EE应用程序)

一边看JVM的内存,我注意到内存从来没有真正释放我让它使用JDBC通过我的连接池的调用后,或需要很长的时间这样做。我检查了我的垃圾收集设置,并且使用了gencon(IBM WebSphere),许多在线资源都表示它很好。我在我的应用程序中也使用了Spring Framework。

我写的连接池类是非常简单的。在初始化时,它创建一定数量的数据库连接并将它们添加到队列中(我尝试了一个简单的Vector实现,但与内存结果相同)。当你请求一个连接时,它会检查并确认有一个可用的连接,如果有的话,它会给一个连接。最后,您将其返回并将其放回Queue/Vector中。

我想知道是否有其他任何可能对这样做?我应该让Spring Framework处理我的连接池吗,还是有更好的方法处理内存?对我来说,这确实有道理,但我对实现连接池并不太熟悉。所有资源都表示要做我正在做的事情,但我假设他们可能正在使用一些内置池化实现。我知道关闭连接是可行的,但由于这是一个自定义的混合解决方案,我不能这么做。

谢谢!

+1

绝对使用现有的池实现,并且绝对让Spring为您处理它。你正在重新发明轮子。 –

回答

4

您的应用程序是否在WebSphere应用程序服务器内运行?它是从应用程序服务器获取其数据源,而不是自己创建它?如果是这样,那么连接和声明已经被合并,并且你不需要自己合并它们。

+0

提及WebSphere的内置连接池。在我的回答中完全忘记了它... – Isaac

+0

应用程序在WAS中运行,是的。我不确定数据源是否来自应用服务器本身,但我不这么认为。正在创建连接: Class.forName(“com.ibm.db2.jcc.DB2Driver”); connection = DriverManager.getConnection(jdbcURL,username,pass); – marothisu

+0

这是在容器下使用JDBC的可怕方法。您的WebSphere配置中是否有JDBC驱动程序定义?和数据源定义? – Isaac

2

确定,第一件事的第一:除非你有一个很好的理由,实现自己的连接池机制是不必要的风险的练习。只有很多连接池机制可供选择 - Spring将是其中之一,雅加达的DBCP是另一个。如果您可以选择使用第三方实用程序进行连接池 - 请执行此操作。如果您正在容器中运行,请让容器为您完成工作(WebSphere已通过其各种“帮助类”执行此操作)。

关于您遇到的症状:事实不是释放内存,并不意味着有内存泄漏。由JVM决定是否以及何时实际释放未引用的对象实例。你是否也遇到OutOfMemory错误?

开始发出一些堆转储(右后JDBC资源释放),看看发生了什么事情在那里。

关于您编写​​的代码 - 无需发布代码,很难猜测您是否存在隐藏的bug;但是你所描述的流程看起来是正确的。

+0

这就是我的想法。我不是原作者,而是进入这个代码库。在其他地方使用了自定义的JDBC池机制(不知道原创作者为什么这么做)。在代码中有一段关于“很遗憾我们不能使用Spring”的评论,但我不确定这是为什么)。我遵循他的惯例,并且也是这样做的)。 嗯,我知道这不是一个内存泄漏(技术上有在Java中的内存泄漏权没有这样的事情?;-)),但它是一个“内存猪。”我们的设置非常高,但是很久之后我们就会遇到内存不足的问题。 – marothisu

+1

古老的土耳其谚语说:“不管你走多远路 - 走回头路。” – Isaac

+0

我很高兴这是一个土耳其谚语。我将在Spring中实现它,希望它能起作用。代码中有一条评论说Spring没有工作,或者有什么影响,但是谁知道他们是否正确实现了它。 – marothisu