2011-03-03 73 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