2010-08-09 56 views
4

我收到此错误: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文件,然后改变

-Xms 256m and -Xmx 512m 

增加堆内存空间的但是这并没有帮助。我试过512m和1024m,但最终出现错误:无法启动JVM和eclipse没有打开。

我试图做同样的CMD线:

java -Xms 256m and -Xmx 512m 

也蚀-vmargs -Xms 256m and -Xmx 512m 但仍然没有帮助。 我基本上是创建一个JDBC连接来查询数据库非常大的记录集。 请帮帮我。

+0

有多少条记录? – 2010-08-09 20:36:38

+0

这是什么类型的应用程序,您可以更详细地了解一旦获得该数据后您想要处理的所有数据?你想展示给用户吗?做计算? – 2010-08-09 21:05:44

回答

8

当你查询返回非常大大集,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驱动程序没有影响)

+0

谢谢你们所有的信息。 stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); //这些是默认值,但我相信 stmt.setFetchSize(Integer.MIN_VALUE); 这工作!所以松了一口气! :) – JJunior 2010-08-09 21:37:38

+0

不幸的是,这个解决方案为Spring(2 mio记录)带来了“流操作结果集不支持的操作”异常。幸运的是,增加Xms确实有帮助。 – 2012-03-05 11:57:54

0

尝试将您的数据拆分为多个结果集。考虑一下从数据库中取回数据后,你想要做什么。结果集太大而不适合堆空间。

0

查询的全部结果是否必须在内存中?如果是,那么你应该购买更多的内存。如果不是的话,那么划分问题将是适当的解决方案。在很多情况下,您甚至可以让数据库为您整合数据。

如果您对给定问题的解决方案不能很好地满足数据量的要求,那么即使通过扩展RAM也会返回到此问题。所以真正好的解决方案是根本避免这种情况。

0

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

1

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

-Xmx是最大Heap大小。尝试增加它,直到您不再获取OutOfMemory异常,或者直到内存不足。

如果内存不足,则无法一次加载整个ResultSet,而需要应用其他人提到的方法。

0

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