Java MySQL JDBC内存泄漏

Jor*_*dan 10 java mysql memory-leaks jdbc

好的,所以我有这个程序有很多(~300)个线程,每个线程都与一个中央数据库通信.我创建了一个到DB的全局连接,然后每个线程都会创建业务创建语句并执行它们.

在某个地方,我有一个巨大的内存泄漏.在分析堆转储后,我看到com.mysql.jdbc.JDBC4Connection对象是70 MB,因为它在"openStatements"(哈希映射)中有800,000个项目.在某个地方它没有正确地关闭我创建的语句,但我不能为我的生活弄清楚在哪里(每次打开一个,我也关闭它).有什么想法可能会发生吗?

Vla*_*lan 22

我有完全相同的问题.我需要为3个线程保持1个连接活动,同时每个线程必须执行大量语句(100k的顺序).我非常小心,我使用try .... finally ...算法关闭了每个语句和每个结果集.这样,即使代码以某种方式失败,语句和结果集也始终关闭.运行代码8小时后,我惊讶地发现必要的内存从最初的35MB到500MB.我生成了一个内存转储,我用Eclipse的Mat Analyzer进行了分析.事实证明,一个com.mysql.jdbc.JDBC4Connection对象占用了445MB的内存,保留了一些openStatements对象,而这些对象依次保留了135k hashmap条目,可能来自所有结果集.因此,即使您关闭所有语句和结果集,如果不关闭连接,它仍会保留对它们的引用,并且GarbageCollector无法释放资源.

我的解决方案:经过长时间的搜索,我发现MySQL的人员发表了这样的声明:

"快速测试是将" dontTrackOpenResources = true " 添加到JDBC URL.如果内存泄漏消失,应用程序中的某些代码路径不会关闭语句和结果集."

这是链接:http://bugs.mysql.com/bug.php?id = 5022.所以我试过了,猜猜怎么着?8小时后,对于相同的数据库操作,我需要大约40MB的内存.也许连接池是可取的,但如果这不是一个选项,这是我遇到的下一个最好的事情.


MJB*_*MJB 1

你知道,除非 MySQL 这么说,否则 JDBC 连接不是线程安全的。除非使用连接池,否则不能跨线程共享它们。此外,正如所指出的,您应该 try/finally 保证所有语句、结果集和连接都关闭。