异常 java.lang.OutOfMemoryError:Java 堆空间
Posted
技术标签:
【中文标题】异常 java.lang.OutOfMemoryError:Java 堆空间【英文标题】:Exception java.lang.OutOfMemoryError: Java heap space 【发布时间】:2016-12-16 14:03:16 【问题描述】:使用的 IDE:Netbeans 8.1。
从 mysql 数据库中读取大数据。下面是我的代码:
List outer=new ArrayList<String>();
List inner=new ArrayList<String>();
Connection con;
Statement stmt;
ResultSet rs;
ResultSetMetaData rsmd;
int columnNumber;
try
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");
stmt=con.createStatement();
rs=stmt.executeQuery("select * from mytable where srno<1000");
rsmd=rs.getMetaData();
columnNumber=rsmd.getColumnCount();
while(rs.next())
for(int i=1;i<columnNumber;i++)
inner.add(rs.getString(i));
outer.add(inner);
System.out.println("\t" + outer);
rs.close();
con.close();
catch(Exception e)
System.out.println(e);
运行代码时出现错误:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
我尝试在属性>运行>VM选项中设置vm选项:-Xmx1024m
我仍然遇到同样的错误。我该如何解决?
【问题讨论】:
查询较小的表或使用 WHERE 子句来限制返回的数据量。运行具有更多 RAM 的 64 位 JVM。这就是你所能做的。 做到了。但仍然遇到同样的错误。 提供有关选择结果的更多详细信息:多少行?有多少列?每列内容的平均大小? 共有 10,67,000 行和 45 列。 假设每列的平均大小为x bytes
,您以x*43MB
结束。如果每列的平均大小是 10 字节,那么堆中有 0.5GB。没办法。
【参考方案1】:
看看这段代码:
while(rs.next())
for(int i=1;i<columnNumber;i++)
inner.add(rs.getString(i));
outer.add(inner);
对于表中的每一行,您将每个列值添加到一个列表中,并且您将每个列表添加到另一个列表中。因此,如果您的表有 100 万行并且每行有 5 列。您正在创建 500 万行。内存被耗尽是不是很奇怪?根据您的更新,它实际上是 1000 万行和 45 列。您是否意识到您正在制作 4.5 亿个对象!
还请记住,由于对象标题和其他内容,外部列表中的每个项目将占用比这些列在数据库中占用的空间量更多的空间。
你已经解释了这是做什么用的,例如,如果它是用于一个摇摆应用程序,你可以选择一个合适的 TableModel 并避免一次将整个 db 加载到内存中。
【讨论】:
哦,我的错。我想将整行存储在一个列表中,并且有多行,这就是这样做的原因。 需要一个完全不同的策略。 我同意@e4c5。从 db(惰性列表或分页列表)读取数据时,您需要使用数据。从潜在的无限数据源加载内存数据从来都不是一个好策略。以上是关于异常 java.lang.OutOfMemoryError:Java 堆空间的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程异常处理 ① ( 根协程异常处理 | 自动传播异常 | 在协程体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根协程异常处理 | 异常传播特性 )
Kotlin 协程协程异常处理 ① ( 根协程异常处理 | 自动传播异常 | 在协程体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根协程异常处理 | 异常传播特性 )