簡體   English   中英

是否保證將拋出Java OutOfMemoryError

[英]Is there a guarantee that Java OutOfMemoryError will be thrown

我有一個Java Spring Boot應用程序。 它是真正的大型應用程序,具有許多服務,並且可以執行許多任務。 我要實現的新任務之一是從Oracle DB讀取一些數據,然后通過其余部分將其發送到某個外部應用程序。

正在讀取的數據相當大(很難說出它包含幾何對象的大小),大約有180萬條記錄需要讀取。

為了解決這個問題,我使用“鍵集分頁”作為從DB讀取的方式。 這意味着我獲得了上一個讀取的ID,然后基於該ID獲取了下一頁(e_id> lastReadId)。 頁面大小為100個實體。

在上一次運行時,它到達頁面'6672'(已讀取667200個實體並將其發送到外部應用程序)。 值得注意的是,我不存儲對這些對象的任何引用,只是獲取頁面,存儲它的列表並通過rest發送它。 在下一次運行時,該列表將被新頁面覆蓋,依此類推。

這是每3小時獲取的實體數的圖表,最大值為1030,最小值為145。

每3小時提取實體

我的問題是該應用程序崩潰了,沒有任何錯誤。 在日志中,我可以看到已經獲取了最后一頁(在本例中為'6672',有時是其他頁面),然后突然有一條日志消息記錄在我的應用程序啟動時。

我首先想到的是它用完了內存,然后崩潰了。 但沒有跡象表明。 是否可以保證在這一點上拋出OutOfMemoryError? 我應該看看別的東西嗎? 也許我做錯了。

編輯

我正在添加一些代碼供您查看如何執行這些操作

// 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

您可以將JVM配置為在收到此錯誤時生成堆轉儲。

要將JVM配置為生成堆轉儲,請將-XX:+ HeapDumpOnOutOfMemoryError選項添加到Java選項中,然后重新啟動JVM。 發生堆空間錯誤時,JVM將創建一個文件,其大小為配置的最大堆大小。

檢查此以獲取詳細信息https://docs.bmc.com/docs/AtriumOrchestratorPlatform/77/troubleshooting-java-virtual-machine-memory-errors-329147248.html

使用JProfiler進行性能分析后,我發現Hibernate將緩存所有選定的內容,因為所有事情都是在單個事務中完成的。 在現有的while循環中添加EntityManager.clear()解決了該問題。

同樣值得注意的是,整個過程大大加快了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM