我有7500行在表用户在MySQL数据库,VM选项:Xmx 8 m和下面的一些代码:
Query query = session.createQuery("select u from User u");
ScrollableResults resultSet = query.setFetchSize(Integer.MIN_VALUE).setReadOnly(true).scroll(ScrollMode.FORWARD_ONLY);
int i = 0;
while (resultSet.next()) {
User o = (User) resultSet.get(0);
System.out.println(o.getId());
i++;
if (i % 50 == 0) {
session.clear();
}
}
resultSet.close();
但不幸的是,我在控制台中有这样的输出:... 5745 Exception in thread“main”java.lang.OutOfMemoryError:超过GC开销限制。
但我不明白为什么??Integer.MIN_VALUE -用作驱动程序的信号,以逐行流式传输结果集。也许我有一个问题,因为ScrollableResults存储在内存和8 m堆是不够的??
2条答案
按热度按时间ar7v8xwq1#
内存使用超出Xmx配置时。JVM可能会尝试收集垃圾以释放足够的内存,而垃圾收集器占用了过多的时间。内存溢出异常“
java.lang.OutOfMemoryError: GC overhead limit exceeded.
“。您必须增加JVM内存的最大数量(Xmx),或者只删除JVM标志以使用默认分配。(假设您有足够的物理内存)Java HotSpot VM Options
Troubleshooting Memory Leaks
由于这是一个很小的数据集(7500),mysql JDBC驱动程序应该能够处理这个问题。请注意,不会从会话中清除最后一批记录。即使从ResultSet部分中的http://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html:
默认情况下,ResultSets被完全检索并存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计,更容易实现。如果您使用的ResultSets具有大量的行或大值,并且无法在JVM中为所需的内存分配堆空间,则可以告诉驱动程序每次将结果流回一行。
您必须检查hibernate和JDBC驱动器版本。
chy5wohz2#
希望这对某人有帮助。
是什么帮助了我: