【问题标题】:Hibernate ScrollableResults OutOfMemoryHibernate ScrollableResults OutOfMemory
【发布时间】:2015-02-05 09:17:47
【问题描述】:

我在 MySQL db 的 Table User 中有 7500 行,VM 选项:-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 线程“主”java.lang.OutOfMemoryError 中的异常:超出 GC 开销限制。

但我不明白为什么? Integer.MIN_VALUE - 用作驱动程序逐行流式传输结果集的信号。也许我有一个问题,因为 ScrollableResults 存储在内存中并且 8m 的堆还不够??

【问题讨论】:

    标签: java mysql hibernate


    【解决方案1】:

    当内存使用超过 Xmx 配置时。 JVM 可能会尝试收集垃圾以释放足够的内存,而垃圾收集器花费了过多的时间。我们出现内存不足异常“java.lang.OutOfMemoryError: GC overhead limit exceeded.”。您必须增加 (Xmx) 最大 JVM 内存量或删除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 网络协议的设计,更容易 实施。如果您使用的结果集数量较多 行或大值,并且无法在 JVM 中为 所需的内存,您可以告诉驱动程序流式传输结果 一次退一排。

    您必须检查休眠和 JDBC 驱动器版本。

    【讨论】:

    猜你喜欢
    • 2011-02-04
    • 2012-04-29
    • 1970-01-01
    • 2010-12-15
    • 2012-04-30
    • 2015-02-07
    • 2018-12-18
    • 2011-02-19
    • 2021-01-04
    相关资源
    最近更新 更多