Java堆内存错误

时间:2010-08-09 20:32:54

标签: java exception jdbc exception-handling

我收到此错误:

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文件然后更改

来增加堆内存空间
-Xms 256m and -Xmx 512m

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

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

java -Xms 256m and -Xmx 512m

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

6 个答案:

答案 0 :(得分:9)

当您查询返回非常大集时,默认情况下,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驱动程序)

答案 1 :(得分:1)

您无需担心-Xms太多 - 这是启动时的初始堆大小。

-Xmx是最大堆大小。尝试增加它,直到你不再获得OutOfMemory异常,或者直到你的内存不足为止。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

Lazy Load适用吗?您是否可以使用上限来限制分段查询的结果?

答案 5 :(得分:0)

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