2011-04-19 87 views
2

我有一個名爲SrcFile和一個其列的實體類是:爲什麼此代碼運行速度越來越慢?

@NotNull 
@Lob 
private Byte[] data; 

SrcFile與報告實體OneToOne關係。

從Report.java:

@OneToOne 
private SrcFile srcFile; 

堅持一個SrcFile實體的偉大工程。

srcFileHomeFacade.clearInstance(); 
SrcFile srcFile = srcFileHomeFacade.getInstance(); 
byte[] bArray = resource.getBytesForSource(); 
srcFile.setData(ReportFileResource.toObject(bArray)); 
System.out.println("````````````````srcFile data length: "+bArray.length); 
srcFileHomeFacade.persist(); 

問題出在我堅持Report

我做的:

report.setSrcFile(srcFile); 
reportHomeFacade.persist(); 

和作品不錯,但多次運行此代碼它變得越來越慢後(即使它引發GC開銷錯誤)和調查的時間後,我發現,這report.setSrcFile(srcFile)是問題。

不知怎的,報告不喜歡引用的srcFile.data這樣的量......

你看到的原因是什麼?

如果我評論report.setSrcFile所有的作品都很好(除了報表中的SRCFILE_ID將爲空,但它僅用於測試)。請注意,數據的長度約爲100.000。

注意:如果我沒有堅持任何report但只有srcFile實體我沒有問題。 UPDATE

「運行慢」解釋:這段代碼被稱爲轉換一些PCLS爲PDF因此data包含PCL的來源,每次都不同了。轉換大約100 pcls後,這個過程變得越來越慢,並且使用虛擬機,我發現了需要大量MB內存的byte []數組。同樣,這絕對不是IO問題,而是關於報告實體上的setSrcFile,VisualVM也指出了這一點。

+2

我會說,因爲它的Java:p – ThiefMaster 2011-04-19 22:39:03

+1

@ThiefMaster:非常有幫助;) – weltraumpirat 2011-04-19 22:42:16

+0

請澄清:當你說「多次運行」時,你的意思是:你多次堅持同一個實體嗎?只有在持續或讀取數據時,程序運行速度是否會變慢?在寫數據的時候你會運行讀操作嗎?你是否在同一份報告中設置了不同的文件,或者它總是與一個報告一樣的srcFile?你設置CascadeTypes嗎?你使用懶惰或渴望加載? – weltraumpirat 2011-04-19 22:50:15

回答

2

我仍然有點不確定,但我懷疑你的問題涉及到你持久化事物和處理實體對象的方式:如果你的實體一旦被持久化就被正確放棄,GC應該釋放足夠的內存來保存您的系統運行平穩。特別是如果你在每次事務之後使用flush()或commit(),你的內存使用量不應該繼續增長。然而,就你而言,似乎所有實體都在內存中,即使不再需要它們 - 所以資源沒有被釋放的原因必須有一定的原因。

你是否有任何機會使用單個for循環迭代一組srcFiles,並在其中直接執行所有persist()調用?如果是這樣,你的問題可能與範圍有關。您可以嘗試將循環的內容提取到新方法,以在每次迭代後正確釋放所有局部變量。

您也可以通過設置CascadeType.PERSIST或CascadeType.ALL並在報告上使用單個persist()操作來保存兩個對象,從而改進事情。 FetchType.LAZY也可能有所幫助。

在任何情況下:尋找可能的原因,爲什麼你的程序會將所有實體直接存儲在內存中,而不是將它們保存到數據庫中,並在事後忘記它們。

+0

考慮到缺少問題中的詳細信息,聽起來非常可能的可能性 – vickirk 2011-04-20 00:28:00

+0

感謝您的詳細解答。我正在使用seam,並且我註釋了這種方法,它使用@Transactional持久化了所有的事務和釋放組件的管理由Seam完成...我將嘗試使用CascadeType.PERSIST。 – 2011-04-20 07:11:36

+0

真是太棒了。它與CascadeType.PERSIST和FetchType.LAZY一起工作......這是否意味着在持久化報告之後,如果報告仍在內存中,srcFile不會被它分離?如果是的話,比所有有意義的,因爲srcFile它是非常巨大的.... – 2011-04-20 07:21:28

0

我記得原生的JDBC接口到BLOB可能會非常棘手,需要手動關閉供應商對象()。如果錯過了這一步,則BLOB被累積在JDBC驅動程序上(即在JVM內存中),最終JVM進入OOM。

不知您是否需要任何供應商特定的屬性或步驟來保存後關閉BLOBs。

相關問題