2011-03-03 74 views
2

JAXB對於編組和解組工作正常。因爲創建marshallers和unmarshallers可能會很慢,使用它們的池(基於contextPath)似乎是一種合理的方法。但是,看起來Unmarshaller在完成後會保持對象。如果它傳遞了一個非常大的文檔,那麼如果該特定的Unmarshaller不會重用一段時間,它可能會保存很多內存。有沒有辦法讓JAXB釋放它處理的對象?JAXB堅持傳遞給Marshaller的對象

JAXBContext jaxBContext = JAXBContext.newInstance(contextPath, loader); 
Unmarshaller unMarshaller = jaxBContext.createUnmarshaller(); 
... 
responseObject = unmarshaller.unmarshal(new StreamSource(new StringReader(xml))); 

有網上池的實例方法是這樣的(例如,一個在阿帕奇:JAXBUtils.java)。當他們把Unmarshaller放回池中時,大多數人似乎沒有做任何特別的事情。

更新:這似乎是JAXB中的一個錯誤:Post-Unmarshall Object Retention。 Marshall中的類似錯誤早已修復,所以它在最新版本的JAXB中。所以現在我想知道(一),如果有一個解決方法與Unmarshaller的(b)本問題,它的Java6的此修復程序是/將被納入英寸

是發生在我
+0

你究竟是什麼意思的「傳遞給它的對象」?你認爲Marshaller在編組完成後是否持有對編組對象的引用? – 2011-03-03 22:04:06

+0

您使用的是JAXB的哪個實現:Metro(RI),EclipseLink MOXy,Apache JaxMe? – 2011-03-03 22:18:54

+0

問題可能是服務器已返回JAXB已處理的20Mb XML文檔情況下的Unmarshaller。後來注意到JVM有很多內存,並且看起來是JAXB池。我相信這是現在與Java 6捆綁在一起的標準JAXB。 – 2011-03-03 22:30:22

回答

2

一個解決辦法是彙集JAXBContext而不是Un/Marshaller。做一些快速的時間,看起來創建Un/Marshaller所花的時間與從contextPath創建JAXBContext所花費的時間相比可以忽略不計。通過只保留對池中的JAXBContext的引用,Unmarshaller應該被釋放,這有希望允許GC回收它的內存以及Unmarshaller由於jaxb錯誤而持有的文檔的內存。

0

另一種可能的解決方法似乎是立即重用UnMarshaller,以便它將從前一個解組中釋放對象。也許傳遞一個有效但基本上爲空的XML文檔,這是一個只需要最外層標籤的字符串。不幸的是,最初的結果似乎並不樂觀。

String xmlStr = "<ns0:SvcData xmlns:ns0=\"http://Company.com/Schemas/Svc/Base\"></ns0:SvcData>"; 
Object o = unMarshaller.unmarshal(new StreamSource(new StringReader(xmlStr))); 
+0

不幸的是,這似乎並沒有工作:( – 2011-03-11 14:13:40

0

http://java.net/jira/browse/JAXB-843

我面臨着與編組相同。我用一個測試程序報告了這個問題。如果您嘗試編組某些愚蠢的東西,則會捕獲並使用問題報告中附件中的異常,然後編組人員會釋放以前使用的資源。

我認爲它值得與unmarshallers一樣的嘗試:)

+0

正如問題中提到的,這也是unmarshaller報告(晚於編組人員),並修復了這個問題,但修復程序在JAXB的後續版本中, t包含在Java6中,所以我們正在尋找解決方法,我認爲彙集JAXBContext而不是Un/Marshaller的答案是 – 2011-06-17 18:15:46

+0

你能告訴我哪個是報告和修復的問題嗎? ://java.net/jira/browse/JAXB-525)看起來像是等待澄清。 – 2011-06-17 20:43:03

+0

對不起,我誤解了你的建議。有趣的是,捕獲異常會導致清理。 – 2011-06-18 16:30:54