tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Shifman <mark.shif...@yale.edu>
Subject Re: JAXBContext leaks memory
Date Tue, 04 May 2010 13:10:13 GMT

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


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 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
> 
> 
> 

-- 
 Mark Shifman MD. Ph.D.
 Yale Center for Medical Informatics
 Phone (203)737-5219
 mark.shifman@yale.edu

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message