[英]Java Heap filling up with JDBC4PreparedStatement
I'm running a Play! 我正在运行一个Play! 2.3 app that is multithreaded using Akka. 2.3使用Akka多线程的应用程序。 Each thread accesses a MySQL database and runs some computations. 每个线程访问一个MySQL数据库并运行一些计算。 Every time I run a set of these tasks, the app's memory footprint increases, largely due to JDBC4PreparedStatement
objects that never go away. 每当我运行一组这些任务时,应用程序的内存占用都会增加,这主要是由于JDBC4PreparedStatement
对象永远不会消失。 After a few runs, these objects take up over 200MB, and soon add up to an out of memory error Calling Sytem.gc()
doesn't lower it at all. 运行几次后,这些对象将占用200MB以上的空间,并很快加成内存不足错误。调用Sytem.gc()
完全不会降低它。
I'm using Hibernate 4.3.0 for persistence, and calling clear()
on the EntityManager
doesn't help either, so it's not that there are persistent objects being stored anywhere. 我正在使用Hibernate 4.3.0进行持久化,并且在EntityManager
上调用clear()
也无济于事,因此并不是在任何地方都存储有持久性对象。 This answer implies that there may be Statement
objects being left open somewhere, but I'm never interfacing directly with Statement
objects or Connection
objects, just with JPA's EntityManager
. 这个答案暗示可能有Statement
对象在某个地方保持打开状态,但是我永远不会直接与Statement
对象或Connection
对象进行接口,而只是与JPA的EntityManager
交互。
Is this expected behavior for MySQL JDBC or JPA? 这是MySQL JDBC或JPA的预期行为吗? How can I solve this memory leak? 我该如何解决此内存泄漏? I'm not sure where to look for solutions, being unsure whether this is issue is due to MySQL or JDBC or JPA or Hibernate's implementation of it. 我不确定在哪里寻找解决方案,不确定这是否是MySQL或JDBC或JPA或Hibernate的实现所致。 Or possibly the way Play! 或可能的方式玩! handles JPA. 处理JPA。
EDIT 编辑
To be clear, I'm not using Connection
or Statement
objects, so there isn't anything for me to close. 需要明确的是,我没有使用Connection
或Statement
对象,因此没有什么可以关闭的。 Here's an example, where I get the EntityManager
from Play in a transaction, do something, then the transaction commits. 这是一个示例,在该示例中,我从事务中的Play获取EntityManager
,执行某些操作,然后提交事务。
JPA.withTransaction( () -> {
Site site= JPA.em().find(Site.class, siteId);
site.setDomain("www.stackoverflow.com");
});
This is expected behavior. 这是预期的行为。 You will have to tell the mysql connection to return a cursor instead of the select of the full set by setting: 您将必须告诉mysql连接返回一个游标,而不是通过设置来选择完整集:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
Your specific settings could be slight different then this based on your requirements, so some fiddling around might be required. 根据您的要求,您的特定设置可能与此稍有不同,因此可能需要一些摆弄。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.