java Hibernate ScrollableResults OutOfMemory

kzipqqlq  于 2023-04-28  发布在  Java
关注(0)|答案(2)|浏览(153)

我有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堆是不够的??

ar7v8xwq

ar7v8xwq1#

内存使用超出Xmx配置时。JVM可能会尝试收集垃圾以释放足够的内存,而垃圾收集器占用了过多的时间。内存溢出异常“java.lang.OutOfMemoryError: GC overhead limit exceeded.“。您必须增加JVM内存的最大数量(Xmx),或者只删除JVM标志以使用默认分配。(假设您有足够的物理内存)
Java HotSpot VM Options
Troubleshooting Memory Leaks

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
默认情况下,ResultSets被完全检索并存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计,更容易实现。如果您使用的ResultSets具有大量的行或大值,并且无法在JVM中为所需的内存分配堆空间,则可以告诉驱动程序每次将结果流回一行。
您必须检查hibernate和JDBC驱动器版本。

chy5wohz

chy5wohz2#

希望这对某人有帮助。
是什么帮助了我:

ScrollableResults<T> results = session.createQuery(criteriaQuery).setFetchSize(100).setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);

相关问题