我收到此错误:
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连接来查询数据库中的大量记录。
请帮我。
答案 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有帮助。