You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicemix.apache.org by Stuart Roe <st...@ovic.co.uk> on 2009/11/23 10:21:54 UTC

Problem with Old Gen memory leak in custom code

Hi all,
 
I appear to have a memory leak while performing an exchange and I'm unsure
how to identify it/correct it. Bascially, my application happily runs for a
few days and then fails with an out of memory exception. Using jconsole I
can see that the memory usage is bouncing around with a slow consistent
creap up. This is why I suspect a memory leak.
 
The message path within the app is:
cxf-bc -> cxf-se -> eip -> jbi-su
all running in SMX 3.3.1/WinXP, smx modules are ver 2009.01.
 
The handler in CXF-SE creates a new InOut message and sync. send it to the
NMR, unmarshals the response into a reply. There is a copy of the sending
and receiving functions below. I have removed the actual data handling and
exceptions.
 
My question is, I'm I missing some form of deallocation/close call that will
return/release an object and hence remove my memory leak?
I have found that replacing the message exchange from the cxf-se handler
with a hard wired response fixes the leak. If I insert a hardwired response
into the processRequest function below (at the short circuit comment) the
memory is still present. This really only leaves the SMX exchange code.
 
Any help/pointers would be helpful.
 
Stuart.
 
BTW:
I'm using JiBX to marshal between NMR XML and Java objects (which may also
be the source of the problem).
 
Sender (cxf-se) Function:
public List<TypeConfigStatus> getConfigStatus()
  try {
    GetConfigStatusResponse response = null;
 
    DeliveryChannel ch = getContext().getDeliveryChannel();
    InOut exch = ch.createExchangeFactory().createInOutExchange();
    exch.setService(getService());
    exch.setInMessage(exch.createMessage());
    exch.getInMessage().setProperty("operation", "config-status");
    exch.getInMessage().setContent(new StringSource("<empty />"));
 
    if(ch.sendSync(exch)){
        NormalizedMessage amsg = exch.getOutMessage();
        try {
          SourceTransformer trans = new SourceTransformer();
          String content = trans.contentToString(amsg);
          IBindingFactory bfact =
BindingDirectory.getFactory(GetConfigStatusResponse.class);
          IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
          response = (GetConfigStatusResponse) uctx.unmarshalDocument(new
StringReader(content));
 
        } catch 
          // block removed
        }finally{
          exch.setStatus(ExchangeStatus.DONE);
          ch.send(exch);
        }
    }
 
    // set result = cooked(response)
 
  return result;
}
 
Receiver (jbi-su) Functions:
public void onMessageExchange(MessageExchange exchange) throws
MessagingException {
  if(ExchangeStatus.ACTIVE != exchange.getStatus()){
   logger.debug("onMessageExchange:"+exchange.getStatus().toString());
   return;
  }else
   logger.debug("onMessageExchange:"+getInMessage(exchange));
    
    try{
      // ...
      processRequest((InOut)exchange);
      // ...
    }finally{
   channel.send(exchange);
    }
}
 
private void processRequest(InOut exch) throws MessagingException {
    
  // create reply information in obj: result
 
  exch.setOutMessage(exch.createMessage());
  
  // Short circuit point
 
  try {
    logger.debug("Marshalling response.");
    IBindingFactory bfact =
BindingDirectory.getFactory(GetConfigStatusResponse.class);
    IMarshallingContext mctx = bfact.createMarshallingContext();
    mctx.setIndent(2);
    StringWriter out = new StringWriter();
 
    mctx.marshalDocument(result, "UTF-8", null, out);
 
    logger.debug("Reply message is " + out.toString() + " items.");
 
    exch.getOutMessage().setContent(new StringSource(out.toString()));
 
  } catch (JiBXException e) {
    logger.error("Marshalling failed", e);
    throw new MessagingException(e);
 
  }
}