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 16:36:30 GMT
Thanks.
I'll try Jconsole.
mas

On 05/04/2010 12:28 PM, Pid wrote:
> 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
>>>
>>>
>>>
>>
> 
> 

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


Mime
View raw message