2012-07-28 69 views
1

我正在使用包括Hibernate數據存儲在內的Java程序進行一些實驗。一個實驗可以包含很多試驗,每個試驗可以有多個試驗。每個實驗都在單個Spring事務中進行。如何避免成功的Hibernate保存之後用完Java堆空間?

當有少量測試時,一切都很好,但隨着數據量的增加,我開始遇到Java堆空間不足的內存問題。考慮到我在單個事務中處理的數據量,內存問題似乎是合理的。

我給這家目前的解決方法是:

Set up and save the initial Experiment 
Run a set of Tests. 
Summarise the Test results and create a Trial record 
Delete the Test records 
Save the completed Trial 
Prompt the Garbage Collector to run 

這工作,我可以使用這個框架進行了廣泛的實驗。但是,我不再有權對詳細的測試記錄執行數據分析,因爲我必須刪除它們以防止出現內存問題。

我想要做的是將測試記錄保存到文件,然後從堆中「卸載」它們。試驗仍然會有一對一的保存測試記錄,但是由於測試已經完成,我不再需要記憶中的細節。

Set up and save the initial Experiment 
Run a set of Tests. 
Summarise the Test results and create a Trial record 
Save the Trial (with cascade saves for all Test records) 
Unload the complete Test records 
Prompt the Garbage Collector to run 

任何人都可以想出一個解決我的問題?

+3

在我看來,你正在努力在內存中做很多事情,並且在單個事務中。爲什麼不創建一個實驗(1個事務),然後1個試驗(1個事務),執行測試,將其結果保存到數據庫(1個事務)中,查詢數據庫以計算總體試驗結果並更新試驗(1交易)。數據庫將用於存儲中間結果,而不是內存或文件。如果你認爲它是一個可以持續數天的手動過程,用GUI來輸入測試結果,那將是你做這件事的方式。 – 2012-07-28 16:52:19

+0

你是如何配置Java堆內存最大大小的? (-Xmx) – Luxspes 2012-07-28 16:55:33

+0

謝謝你的評論。 @JB Nizet:我簡化了這個問題的過程。交易被放置在正確的邏輯點上,但我會給它更多的思考。 – MarkA 2012-07-28 20:24:57

回答

2

爲了防止您的對象進入Hibernate Session(並且能夠被垃圾回收),您應該簡單地將您的對象從Hibernates會話中分離出來(使用session.evict())。在你的情況下,你應該在每次保存Trial後遍歷所有Test實例,驅逐它們,然後驅逐你的Trial

當您再次需要對象時,可以使用常規Hibernate方法(加載或查詢)再次加載對象。如果不需要,你應該考慮在Trial.test上延遲加載。

相關問題