代码之家  ›  专栏  ›  技术社区  ›  mirzak

有没有保证Java OutOfMemoryError会被抛出

  •  0
  • mirzak  · 技术社区  · 6 年前

    我有一个javaspring启动程序。它的应用程序非常大,有很多服务,可以执行一系列任务。我正在尝试实现的新任务之一是从oracledb读取一些数据,并通过rest将其发送到一些外部应用程序。

    正在读取的数据非常大(很难说有多大,它包含几何体对象),大约有180万条记录要读取。

    为了处理这个问题,我使用“键集分页”作为从DB读取数据的一种方式。这意味着我获取最后一个读取的id,然后基于该id获取下一页(e\u id>lastReadId)。页面大小为100个实体。

    上一次运行时,它到达了“6672”页(667200个实体已被读取并发送到外部应用程序)。值得注意的是,我没有存储对这些对象的任何引用,只是获取一个页面,将其存储为一个列表并通过rest发送。在下一次运行时,该列表将被一个新页面覆盖,以此类推。

    Fetched entities per 3h

    我的问题是,应用程序崩溃没有任何错误。在日志中,我可以看到最后一页已经被获取(在本例中是“6672”,有时是另一页),然后突然有一个日志消息在我的应用程序启动时被记录。

    编辑

    // Get first page, last read id is null
    List<MyEntity> data = dataService.collectData(pageSize, null);
    
    sendDataToExternalService(data);
    while(true) {
        final String lastReadID = data.get(data.size() - 1).getId();
        data = dataService.collectData(pageSize, lastReadID);
        sendDataToExternalService(data);
    }
    

    方法 sendDataToExternalService 看起来像这样

    restTemplate.exchange("some/url/to-external-app", HttpMethod.PUT, new HttpEntity<>(data), List.class);
    

    RestTemplate是 org.springframework.web.client.RestTemplate

    2 回复  |  直到 6 年前
        1
  •  1
  •   Sugan    6 年前

    您可以将JVM配置为在收到此错误时生成堆转储。

    要将JVM配置为生成堆转储,请将-XX:+HeapDumpOnOutOfMemoryError选项添加到Java选项中,然后重新启动JVM。当发生堆空间错误时,JVM将创建一个文件,其大小为配置的最大堆大小。

    https://docs.bmc.com/docs/AtriumOrchestratorPlatform/77/troubleshooting-java-virtual-machine-memory-errors-329147248.html

        2
  •  0
  •   mirzak    6 年前

    在使用JProfiler进行了一些评测之后,我发现Hibernate会缓存所有选中的内容,因为所有内容都是在单个事务中完成的。添加 在现有的while循环中解决了这个问题。

    另外值得注意的是,整个过程大大加快。