tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pid <...@pidster.com>
Subject Re: JAXBContext leaks memory
Date Tue, 04 May 2010 16:28:56 GMT
On 04/05/2010 14:10, Mark Shifman wrote:
> 
> On 05/03/2010 02:53 PM, Pid wrote:
>> On 03/05/2010 18:30, Mark Shifman wrote:
>>>
>>> On 05/03/2010 12:48 PM, Pid wrote:
>>>> On 03/05/2010 17:15, Mark Shifman wrote:
>>>>> I have a web app running under tomcat-6.0.26 with JreMemoryLeakPreventionListener,
java jdk1.6.0_18.
>>>>>
>>>>> Using jmap -histo pid, I can watch com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl,
etc increase in number
>>>>> after running my unmarshal action, followed by undeploy and redeploy.
 Find Leaks in the manager also finds leaks.
>>
>> Do you see log messages referring to potential leaks in the catalina.out
>> log (assuming you're on a unix variant)?
>>
>> If so, can you post them please?
> 
> There are no messages in catalia.out concerning leaks (I am using Linux  	2.6.18-92.1.22.el5)
> I also got rid of timeBetweenEvictionRunsMillis in datasource since it causes a leaky
TimerThread).
> 
>>
>> What does the manager 'find leaks' command report exactly?
> ...
> leak (use a profiler to confirm):
> /yp_results

There are some useful commands in the JDK which may help track down
exactly which class is causing the problem.

 jmap -histo <pid>

(and other jmap subcommands)

If you take a snapshot periodically, esp after reload cycles you may be
able to see which classes are increasing in number.


If you can get a VisualVM working, or connect a JConsole to the remote
VM you may be able to poke around and see which classes aren't being
garbage collected.


> My webapp is named yp_results.
>>
>>>> After a few undeploy/redeploy cycles does the number of
>>>> WebappClassLoader's also increase?
>>>
>>> Yes it increases 1 for each undeploy/redeploy cycle.
>>
>>> snip... <
>>
>>>> Maybe.
>>>>
>>>>> JAXBContext.newInstance() can take a ClassLoader argument.  Is there
some ClassLoader I should be using that will get around this?
>>
>> OK, so I've looked at JAXBContext (and JAXBContextImpl) and it doesn't
>> (after quick read through) look like it's storing the classloader
>> argument anywhere during the newInstance call, which is the usual source
>> of leaks.


>>>> Where is the jar with the above code, in a webapp?
>>> The code above in in the war for the web app in a class in WEB-INF/classes/org/blablabla
>>>
>>> It is called via a class that looks like this:
>>>
>>> public class JAXBMascot {
>>> 	protected static Log log = LogFactory.getLog(JAXBMascot.class);
>>> 	private XMLEventReader reader;
>>> 	private Unmarshaller u = JAXBContextMascot.INSTANCE.createUnmarshaller();
>>
>> You're setting the XMLEventReader, Unmarshaller & InputStream as
>> instance field values, rather than completing the parsing in the
>> getInstance() method?
> I have really big xmls to unmarshall so I am using streaming them in and unmarshalling
the elements I want
> and then insert into my database. I need the reader to see where I am and then the umarshaller

I'll have a look at the code below a bit later, am pushed for time right
now.


p



> I didn't show the all the methods of JAXBMascot but here is workhorse:
> 	public <T> T getNextElement(String theElement, String elementAfter, Class <T>clazz)
{
> 		String elname = "";
> 		T h = null;
> 		try {
> 			while(reader.hasNext()){
> 			  if(reader.peek().isStartElement()){
> 				 elname = reader.peek().asStartElement().getName().getLocalPart();
> 				 if(elname.equals(theElement)){
> 			  	       h= u.unmarshal(reader, clazz).getValue();
> 			  	       return h;
> 				 }
> 			  } else if(reader.peek().isEndElement()){
> 					elname = reader.peek().asEndElement().getName().getLocalPart();
> 					if(elname.equals(elementAfter)){
> 						return h;
> 					}
> 				}
> 
> 			  reader.nextEvent();
> 			}
> 		} catch (XMLStreamException e) {
> 			throw new RuntimeException(e);
> 		} catch (JAXBException e) {
> 			throw new RuntimeException(e);
> 		}
> 		return h;
>     }
> 
> It also has a close method to clean up after I have gotten all the elements.
> 	public void close(){
> 		try {
> 			reader.close();
> 		} catch (XMLStreamException e) {
> 			//quietly
> 		}
> 		IOUtils.closeQuietly(jxb_in);
> 		u=null;
> 	}
> I don't think I am leaving any stuff hanging around but memory leaks are very sneaky.
> mas
>>
>> This looks a bit odd to me, but I don't know what the rest of the
>> instance does...
>>
>>
>> p
>>
>>> 	private InputStream jxb_in;
>>>
>>> 	public static JAXBMascot getInstance(InputStream in) {
>>> 		JAXBMascot m = new JAXBMascot();
>>> 		try {
>>> 			m.setJxb_in(in);
>>> 			m.setReader(XMLInputFactory.newInstance().createXMLEventReader(in));
>>> 		} catch (Exception e) {
>>> 			log.fatal("error getting JAXBMascot instance");
>>> 			IOUtils.closeQuietly(in);
>>> 			throw new RuntimeException(e);
>>> 		}
>>>
>>> 		return m;
>>> 	}
>>> ....
>>> }
>>>
>>> This is also in the webapp in WEB-INF/classes/org/blablabla
>>
>>
>>
> 



Mime
View raw message