我在MySQL db,VM选项中的表用户中有7500行:-Xmx8m以及下面的一些代码:
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 线程" main"中的例外情况java.lang.OutOfMemoryError:超出GC开销限制。
但我不明白为什么? Integer.MIN_VALUE - 用作驱动程序逐行传输结果集的信号。也许我有一个问题导致ScrollableResults存储在内存和8m的堆中是不够的?
答案 0 :(得分:0)
当内存使用量超过Xmx配置时。 JVM可能会尝试收集垃圾来释放足够的内存,垃圾收集器花费了过多的时间。我们内存异常" java.lang.OutOfMemoryError: GC overhead limit exceeded.
"。你必须增加(Xmx)最大量的JVM内存或只是删除JVM标志以使用默认分配。 (假设你有足够的物理记忆)
C:\>java -X
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
The -X options are non-standard and subject to change without notice.
由于这是一小组数据(7500),mysql JDBC驱动程序应该能够处理这个问题。请注意,最后一批记录不会从会话中清除。即使来自ResultSet部分中的http://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html:
默认情况下,完全检索并存储ResultSet 在大多数情况下,这是最有效的操作方式, 由于MySQL网络协议的设计,更容易 实行。如果您正在使用具有大量数字的ResultSet 行或大值,并且无法在JVM中分配堆空间 所需的内存,您可以告诉驱动程序流式传输结果 一次回一行。
您必须检查休眠和JDBC驱动器版本。