【问题标题】:is there a way to fetch records from mysql beyond ArrayList max size有没有办法从 mysql 中获取超出 ArrayList 最大大小的记录
【发布时间】:2018-12-27 16:19:46
【问题描述】:

我无法将获取的记录添加到ArrayList 对象,因为ArrayList 的最大大小为Integer.max,并且对mysql 数据库的查询正在检索比Integer.max 太多的记录。

我参与了spring boot 项目。我们需要一个解决方案来使用spring data jpamysql 数据库中获取记录。以下是我获取记录的代码:

@Override
public List<HtsLogs> getAllRecords(String from, String to) {
    System.out.println(from+"                "+to);
    List<HtsLogs> listHtsLogs = new ArrayList<HtsLogs>();
    try {
        String sql =  "SELECT em.* FROM local_backup.hts_logs as em  where em.created_date between ? and ? order by em.created_date desc ;";
        Query query = entityManager.createNativeQuery(sql,HtsLogs.class);
        query.setParameter(1, from);
        query.setParameter(2, to);
        listHtsLogs = query.getResultList();
    }catch(Exception ex) {
        System.out.println("exception HtsLOGS exception HtsLOGS exception HtsLOGS ");
        ex.printStackTrace();
    }
    return listHtsLogs;
}

我希望一次在 arraylist 对象中累积所有记录,但由于最大大小,我无法这样做。我收到java.lang.OutOfMemoryError: GC overhead limit exceeded 错误。有什么解决办法吗..

【问题讨论】:

  • 我们已经知道会有大量非常大量的数据来自 mysql.. 我们正在将其迁移到 mongodb
  • 列表中元素的最大数量为 2^31。假设列表的每个元素只占用 16 个字节(这是完全空对象的最小值:小于 Integer 占用的字节数)。因此,您需要 16 * 2^31 字节,即 32GB 来将该列表保存在内存中。你有 32GB 的堆大小吗?现在您的项目可能要大得多。假设每个只有 160 个字节(仍然很小)。您将需要 320 GB 的堆。你有吗?将所有内容加载到内存中没有任何意义。
  • 尝试使用批处理概念。这里只是一个指导方针websystique.com/springbatch/…
  • 顺便说一句,我怀疑你的表中有那么多行。 OutOfMemoryError 意味着您的内存不足,而不是您试图用比其最大大小更多的元素填充列表。尽管如此,将所有内容加载到内存中并不是一个好的策略,使用 JPA 可能也不是,但是您还没有告诉我们您想要实现的目标。
  • @JBNizet 感谢您在这里的努力。他们为我们提供了丰富的信息。我们已经使用nohup java -jar -Xms1024m -Xmx6144m -XX:PermSize=1024m -XX:MaxPermSize=1024m springmongo-0.0.1-SNAPSHOT.jar &amp; 运行了 jar。 mysql 中的 HtsLogs 表包含太多数据无法处理。我们需要一个实用程序来将这些数据存储在我们的备份 mongodb 实例中。

标签: java spring-data-jpa


【解决方案1】:

将所有内容加载到内存中是导致OutOfMemoryError 的原因,而不是 ArrayList 最大大小限制。

对于这种情况,Spring Data JPA 提供了分页的机制。这是一个例子:

import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface EmployeeRepository extends CrudRepository<Employee, Long> {

  public List<Employee> findByDept(String deptName, Pageable pageable);
}

其中Pageable是分页信息的接口。

【讨论】:

    【解决方案2】:

    如果增加 Xmx 不够或不可能,并且分页也不是一个选项,您可以检查 HtsLogs 对象。它可以通过为其字段选择不同的数据类型来优化它以提高内存效率。

    请记住,对于该列表中的每个条目,该对象中的任何次优内容都会相乘,并且如果您确实有大量如此重要的条目。

    【讨论】:

    • S O L V E D. 在Mongo DB 中插入数据时,我使用的是GridFS。为了从平面文件中读取,我使用了InputStream。我忘记了close。所以现在问题解决了。
    猜你喜欢
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多