Java堆内存错误

我收到此错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.mysql.jdbc.MysqlIO.nextRowFast(MysqlIO.java:1585) at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1409) at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:2886) at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:476) at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:2581) at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:1757) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2171) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2562) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2512) at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1476) at DBase.connect(automateExport.java:31) at automateExport.main(automateExport.java:10) 

我尝试通过打开eclipse.ini文件然后更改来增加堆memmory空间

 -Xms 256m and -Xmx 512m 

但这没有帮助。 我尝试了512m和1024m,但最终给出了错误:无法启动JVM并且eclipse没有打开。

我尝试在cmd行上做同样的事情:

 java -Xms 256m and -Xmx 512m 

还有eclipse -vmargs -Xms 256m and -Xmx 512m但仍然没有帮助。 我基本上创建了一个JDBC连接来查询数据库中的大量记录。 请帮帮我。

当您查询返回非常大的集时,mysql驱动程序将默认将整个结果集加载到内存中,然后再进行控制。 听起来你只是内存耗尽,所以增加内存,例如-Xmx1024M

另一种方法可能是在MySQL查询中启用流式传输结果 – 这可以防止整个ResultSet一次性加载到内存中。 这可以通过做

 stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);//These are defaults though,I believe stmt.setFetchSize(Integer.MIN_VALUE); 

(注意除Integer.MIN_VALUE之外的任何其他内容对MySQL驱动程序没有影响)

您不必担心-Xms太多 – 这是启动时的初始堆大小。

-Xmx是最大堆大小。 尝试增加它,直到你不再获得OutOfMemoryexception,或直到你的内存不足。

如果内存不足,则无法立即加载整个ResultSet,并且您需要应用其他人提到的方法。

尝试将数据拆分为多个结果集。 想一想从数据库中取回数据后要对数据做什么。 结果集太大,无法容纳堆空间。

查询的整个结果必须在内存中吗? 如果是,那么你应该购买更多的RAM。 如果没有,那么分区问题将是正确的解决方案。 在许多情况下,您甚至可以让数据库为您整合数据。

如果您针对给定问题的解决方案无法很好地扩展数据量,那么即使扩展RAM,您也会遇到此问题。 所以真正好的解决方案就是避免这种情况。

延迟加载是否适用? 您是否可以使用上限来限制分段查询的结果?

我发现MySql驱动程序有内存泄漏。 我在连接池设置中使用它与tomcat。 JDBCResultSet和StatementImpl对象的加载位于堆中。 在tomcat中设置数据源配置(context.xml)中的maxAge有所帮助。