You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@servicemix.apache.org by KBerthelot <kb...@edgenet.com> on 2007/05/03 05:45:21 UTC

Memory Leak in BeanEndpoint?

I'm getting a memory leak when using the BeanComponent that results from
Request objects never being removed from the requests map in BeanEndpoint. 
In my case I've got a http consumer endpoint with the target service
implemented by a BeanEndpoint.  When onProviderExchange() executes on the
BeanEndpoint, onMessageExchange() is invoked on the pojo, which sends a
response back to the HttpEndpoint.  The problem is that checkEndOfRequest()
executes on the BeanEndpoint before the http ConsumerProcessor has processed
the response message from the pojo and set the exchange status to
ExchangeStatus.DONE.  Therefore the Request object doesn't get removed from
the requests Map.  It would be a bit messy, but it seems like there should
be a way to expire Request objects since it seems like it's fairly easy for
them to get orphaned.  In fact, I'm not sure how you could avoid orphans for
InOut exchanges since I'm not aware of a way to guarantee that the exchange
is complete before onProviderExchange() finishes execution.  Am I missing
something?
-- 
View this message in context: http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tf3684455s12049.html#a10298559
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: Memory Leak in BeanEndpoint?

Posted by rmayo <ma...@hotmail.com>.
It looks like there are open Jira bugs for these issues:

#1 is addressed here: http://issues.apache.org/activemq/browse/SMXCOMP-26

#2 is addressed here: http://issues.apache.org/activemq/browse/SMXCOMP-24



rmayo wrote:
> 
> Thanks for the response Ron.  I checked out the issue, but I believe there
> may be a different issue which can also lead to orphaned Request objects
> in the BeanEndpoint.requests map when multiple threads are sending
> requests concurrently.
> 
> 1) I believe the synchoronize block may need to be moved around the entire
> onProviderExchange() method, otherwise the currentRequest variable can be
> corrupted (one thread overwriting a previous threads value).  The current
> synchronize block can also allow threads to enter the block before the
> bean/beanInfo object have been initalized causing the methodInvocation to
> fail.
> 
> 2) Also in the onProviderExchange() method, I believe the calls at the end
> of the method to:
> 
>             checkEndOfRequest(req);
>             currentRequest.set(null);
> 
> need to be placed inside a finally block.  If not, when a consumer
> responds with a DONE status or if an ERROR occurs, the method just returns
> without cleaning up the requests map or the currentRequest.
> 
> An example where #2 will cause a memory leak is when an InOut exchange is
> received, the initial request will be passed to the bean.  After the bean
> returns, the consumer may have already received the "out" repsonse and set
> the status to DONE (although the deliveryChannel has not yet invoked the
> process() method yet), so the call to checkEndOfRequest(req) at the end of
> onProviderExchange() will remove the Request object from the requests map. 
> When then deliveryChannel does eventually invoke the process() method and
> the process() method invokes the onProviderExchange(), a new Request
> object will be created in getOrCreateCurrentRequest(exchange), but this
> new Request will never be removed from the requests map since the method
> simply returns when the exchange status == DONE.  Moving the calls above
> to a finally block will make sure clean up is performed regardless of
> exchange status and or errors.
> 
> 
> I apologize for the lack of an example to reproduce the problem, I do not
> have access to the internet from my office.
> 
> 
> 
> rgavlin wrote:
>> 
>> 
>> I believe you may have encountered issue
>> https://issues.apache.org/activemq/browse/SMXCOMP-20. This issue has
>> already been fixed.
>> 
>> /Ron
>> 
>> 
>> 
>> ----- Original Message ----
>> From: rmayo <ma...@hotmail.com>
>> To: users@servicemix.apache.org
>> Sent: Tuesday, March 24, 2009 9:59:25 AM
>> Subject: Re: Memory Leak in BeanEndpoint?
>> 
>> 
>> I haven't seen any other postings or replies to this post.  I believe
>> this
>> problem still exists today.  
>> 
>> The only way I can prevent the memory leak from occurring is by casting
>> the
>> MessageExchange to a MessageExchangeImpl and setting the status of the
>> packet to ExchangeStatus.DONE explictly before returning from my pojo, so
>> that BeanEndpoint.checkEndOfRequest() will remove the Request object from
>> the requests Map : 
>> 
>> channel.send(exchange);
>> ((MessageExchangeImpl)
>> exchange).getPacket().setStatus(ExchangeStatus.DONE);
>> 
>> Using channel.sendSync() would work also since my pojo would block until
>> the
>> consumer had responded after setting the status to DONE, but calling
>> sendSync is not desired. 
>> 
>> 
>> Am I missing something too?
>> 
>> 
>> 
>> KBerthelot wrote:
>>> 
>>> I'm getting a memory leak when using the BeanComponent that results from
>>> Request objects never being removed from the requests map in
>>> BeanEndpoint. 
>>> In my case I've got a http consumer endpoint with the target service
>>> implemented by a BeanEndpoint.  When onProviderExchange() executes on
>>> the
>>> BeanEndpoint, onMessageExchange() is invoked on the pojo, which sends a
>>> response back to the HttpEndpoint.  The problem is that
>>> checkEndOfRequest() executes on the BeanEndpoint before the http
>>> ConsumerProcessor has processed the response message from the pojo and
>>> set
>>> the exchange status to ExchangeStatus.DONE.  Therefore the Request
>>> object
>>> doesn't get removed from the requests Map.  It would be a bit messy, but
>>> it seems like there should be a way to expire Request objects since it
>>> seems like it's fairly easy for them to get orphaned.  In fact, I'm not
>>> sure how you could avoid orphans for InOut exchanges since I'm not aware
>>> of a way to guarantee that the exchange is complete before
>>> onProviderExchange() finishes execution.  Am I missing something?
>>> 
>> 
>> -- 
>> View this message in context:
>> http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22681014.html
>> Sent from the ServiceMix - User mailing list archive at Nabble.com.
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22745196.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: Memory Leak in BeanEndpoint?

Posted by rmayo <ma...@hotmail.com>.
Thanks for the response Ron.  I checked out the issue, but I believe there
may be a different issue which can also lead to orphaned Request objects in
the BeanEndpoint.requests map when multiple threads are sending requests
concurrently.

1) I believe the synchoronize block may need to be moved around the entire
onProviderExchange() method, otherwise the currentRequest variable can be
corrupted (one thread overwriting a previous threads value).  The current
synchronize block can also allow threads to enter the block before the
bean/beanInfo object have been initalized causing the methodInvocation to
fail.

2) Also in the onProviderExchange() method, I believe the calls at the end
of the method to:

            checkEndOfRequest(req);
            currentRequest.set(null);

need to be placed inside a finally block.  If not, when a consumer responds
with a DONE status or if an ERROR occurs, the method just returns without
cleaning up the requests map or the currentRequest.

An example where #2 will cause a memory leak is when an InOut exchange is
received, the initial request will be passed to the bean.  After the bean
returns, the consumer may have already received the "out" repsonse and set
the status to DONE (although the deliveryChannel has not yet invoked the
process() method yet), so the call to checkEndOfRequest(req) at the end of
onProviderExchange() will remove the Request object from the requests map. 
When then deliveryChannel does eventually invoke the process() method and
the process() method invokes the onProviderExchange(), a new Request object
will be created in getOrCreateCurrentRequest(exchange), but this new Request
will never be removed from the requests map since the method simply returns
when the exchange status == DONE.  Moving the calls above to a finally block
will make sure clean up is performed regardless of exchange status and or
errors.


I apologize for the lack of an example to reproduce the problem, I do not
have access to the internet from my office.



rgavlin wrote:
> 
> 
> I believe you may have encountered issue
> https://issues.apache.org/activemq/browse/SMXCOMP-20. This issue has
> already been fixed.
> 
> /Ron
> 
> 
> 
> ----- Original Message ----
> From: rmayo <ma...@hotmail.com>
> To: users@servicemix.apache.org
> Sent: Tuesday, March 24, 2009 9:59:25 AM
> Subject: Re: Memory Leak in BeanEndpoint?
> 
> 
> I haven't seen any other postings or replies to this post.  I believe this
> problem still exists today.  
> 
> The only way I can prevent the memory leak from occurring is by casting
> the
> MessageExchange to a MessageExchangeImpl and setting the status of the
> packet to ExchangeStatus.DONE explictly before returning from my pojo, so
> that BeanEndpoint.checkEndOfRequest() will remove the Request object from
> the requests Map : 
> 
> channel.send(exchange);
> ((MessageExchangeImpl)
> exchange).getPacket().setStatus(ExchangeStatus.DONE);
> 
> Using channel.sendSync() would work also since my pojo would block until
> the
> consumer had responded after setting the status to DONE, but calling
> sendSync is not desired. 
> 
> 
> Am I missing something too?
> 
> 
> 
> KBerthelot wrote:
>> 
>> I'm getting a memory leak when using the BeanComponent that results from
>> Request objects never being removed from the requests map in
>> BeanEndpoint. 
>> In my case I've got a http consumer endpoint with the target service
>> implemented by a BeanEndpoint.  When onProviderExchange() executes on the
>> BeanEndpoint, onMessageExchange() is invoked on the pojo, which sends a
>> response back to the HttpEndpoint.  The problem is that
>> checkEndOfRequest() executes on the BeanEndpoint before the http
>> ConsumerProcessor has processed the response message from the pojo and
>> set
>> the exchange status to ExchangeStatus.DONE.  Therefore the Request object
>> doesn't get removed from the requests Map.  It would be a bit messy, but
>> it seems like there should be a way to expire Request objects since it
>> seems like it's fairly easy for them to get orphaned.  In fact, I'm not
>> sure how you could avoid orphans for InOut exchanges since I'm not aware
>> of a way to guarantee that the exchange is complete before
>> onProviderExchange() finishes execution.  Am I missing something?
>> 
> 
> -- 
> View this message in context:
> http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22681014.html
> Sent from the ServiceMix - User mailing list archive at Nabble.com.
> 
> 

-- 
View this message in context: http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22709191.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.


Re: Memory Leak in BeanEndpoint?

Posted by Ron Gavlin <rg...@yahoo.com>.
I believe you may have encountered issue https://issues.apache.org/activemq/browse/SMXCOMP-20. This issue has already been fixed.

/Ron



----- Original Message ----
From: rmayo <ma...@hotmail.com>
To: users@servicemix.apache.org
Sent: Tuesday, March 24, 2009 9:59:25 AM
Subject: Re: Memory Leak in BeanEndpoint?


I haven't seen any other postings or replies to this post.  I believe this
problem still exists today.  

The only way I can prevent the memory leak from occurring is by casting the
MessageExchange to a MessageExchangeImpl and setting the status of the
packet to ExchangeStatus.DONE explictly before returning from my pojo, so
that BeanEndpoint.checkEndOfRequest() will remove the Request object from
the requests Map : 

channel.send(exchange);
((MessageExchangeImpl) exchange).getPacket().setStatus(ExchangeStatus.DONE);

Using channel.sendSync() would work also since my pojo would block until the
consumer had responded after setting the status to DONE, but calling
sendSync is not desired. 


Am I missing something too?



KBerthelot wrote:
> 
> I'm getting a memory leak when using the BeanComponent that results from
> Request objects never being removed from the requests map in BeanEndpoint. 
> In my case I've got a http consumer endpoint with the target service
> implemented by a BeanEndpoint.  When onProviderExchange() executes on the
> BeanEndpoint, onMessageExchange() is invoked on the pojo, which sends a
> response back to the HttpEndpoint.  The problem is that
> checkEndOfRequest() executes on the BeanEndpoint before the http
> ConsumerProcessor has processed the response message from the pojo and set
> the exchange status to ExchangeStatus.DONE.  Therefore the Request object
> doesn't get removed from the requests Map.  It would be a bit messy, but
> it seems like there should be a way to expire Request objects since it
> seems like it's fairly easy for them to get orphaned.  In fact, I'm not
> sure how you could avoid orphans for InOut exchanges since I'm not aware
> of a way to guarantee that the exchange is complete before
> onProviderExchange() finishes execution.  Am I missing something?
> 

-- 
View this message in context: http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22681014.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.

Re: Memory Leak in BeanEndpoint?

Posted by rmayo <ma...@hotmail.com>.
I haven't seen any other postings or replies to this post.  I believe this
problem still exists today.  

The only way I can prevent the memory leak from occurring is by casting the
MessageExchange to a MessageExchangeImpl and setting the status of the
packet to ExchangeStatus.DONE explictly before returning from my pojo, so
that BeanEndpoint.checkEndOfRequest() will remove the Request object from
the requests Map : 

channel.send(exchange);
((MessageExchangeImpl) exchange).getPacket().setStatus(ExchangeStatus.DONE);

Using channel.sendSync() would work also since my pojo would block until the
consumer had responded after setting the status to DONE, but calling
sendSync is not desired. 


Am I missing something too?



KBerthelot wrote:
> 
> I'm getting a memory leak when using the BeanComponent that results from
> Request objects never being removed from the requests map in BeanEndpoint. 
> In my case I've got a http consumer endpoint with the target service
> implemented by a BeanEndpoint.  When onProviderExchange() executes on the
> BeanEndpoint, onMessageExchange() is invoked on the pojo, which sends a
> response back to the HttpEndpoint.  The problem is that
> checkEndOfRequest() executes on the BeanEndpoint before the http
> ConsumerProcessor has processed the response message from the pojo and set
> the exchange status to ExchangeStatus.DONE.  Therefore the Request object
> doesn't get removed from the requests Map.  It would be a bit messy, but
> it seems like there should be a way to expire Request objects since it
> seems like it's fairly easy for them to get orphaned.  In fact, I'm not
> sure how you could avoid orphans for InOut exchanges since I'm not aware
> of a way to guarantee that the exchange is complete before
> onProviderExchange() finishes execution.  Am I missing something?
> 

-- 
View this message in context: http://www.nabble.com/Memory-Leak-in-BeanEndpoint--tp10298559p22681014.html
Sent from the ServiceMix - User mailing list archive at Nabble.com.