【问题标题】:java.lang.OutOfMemoryError: Java heap space in hibernate while picking 200 thousand rowsjava.lang.OutOfMemoryError:Java 堆空间在休眠时选择 20 万行
【发布时间】:2018-02-06 22:13:00
【问题描述】:

我正在使用 hibernate 4.3.10、java 1.8 和 eclipse neon。 我一直在尝试在我的代码中执行以下语句。但是

java.lang.OutOfMemoryError: Java 堆空间

几分钟后被扔到第二行。

Query query = mySqlSession.createSQLQuery("select * from hops where processed is null");
List<Object[]> lis=query.list();

问题是这个查询返回了大约 200k 的结果,这导致了问题。我参考过 How to deal with "java.lang.OutOfMemoryError: Java heap space" error (64MB heap size)

从上述链接阅读解决方案后,我将内存更改为 2 GB。好像还是有问题。 有什么建议吗?

【问题讨论】:

  • 是否有可能不将 200k 记录放入内存?
  • 必须更改算法以仅使用当前记录(当前:将所有记录放入 RAM)。顺便说一句,为什么对经典查询使用休眠?
  • 顺便说一句,您将获得 * 所有列。它们都需要吗?
  • 我需要一次性处理所有这些记录。此外,我在 hops 表中没有顺序标识符,我可以选择说 10k 先处理它们,然后再处理下一个 10k。

标签: java mysql eclipse hibernate


【解决方案1】:

根据您对行所做的操作,处理这种情况的正确方法是使用 LIMIT 一次只检索部分结果。

然后,当行可用时,您将循环查询并处理结果集。

SELECT * FROM hops WHERE processed IS NULL LIMIT 10000

使用非本地查询时,请参阅@Stefano 的回答。

【讨论】:

    【解决方案2】:

    实际问题是返回如此大的数据集。即使您增加进程内存,当更多数据进入存储时,您也会再次遇到此问题。您可能想在此处实现分页。即获取有限且小的数据集,然后根据请求获取下一页。

    【讨论】:

    • 对。我是这么想的,但我没有一个字段可以帮助我选择一个小集合,然后再选择另一个小集合,依此类推
    • 这就像挑选一批处理为空的数据。
    • 绝对正确。我将只在处理后设置不为空,但到目前为止它们都是空的。
    【解决方案3】:

    我认为有两种方式:

    1.分页(每次查询只选择N行)

    Criteria c = session.createCriteria(Envelope.class);
    List<Envelope> list = c.setMaxResults(10).list();
    

    2.Scrollable Result(类似于JDBC ResultSet)

    Criteria c = session.createCriteria(Envelope.class);
    ScrollableResults scroll = c.scroll(ScrollMode.FORWARD_ONLY);
    while (scroll.next()) {
        Envelope e = (Envelope) scroll.get(0);
        // do whatever
    }
    

    您也可以使用StetelessSession

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-08
      • 2015-05-14
      • 2019-07-10
      相关资源
      最近更新 更多