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 >> >> >> >
signature.asc
Description: OpenPGP digital signature