[ 
https://issues.apache.org/jira/browse/DIRMINA-1086?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16500314#comment-16500314
 ] 

Emmanuel Lecharny commented on DIRMINA-1086:
--------------------------------------------

The only place the map is emptied is in {{removeSessions}}, and only when the 
SelectionKey is still valid. If for any reason this SelectionKey has been 
cancelled, then we will never remove the session from the map...

Anyway, testing it right now.

> IoSessions closed by filterChain.fireExceptionCaught(e) are kept in memory
> --------------------------------------------------------------------------
>
>                 Key: DIRMINA-1086
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-1086
>             Project: MINA
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.0.17
>         Environment: mina in ApacheDS
>            Reporter: Wenxiang Qiu
>            Priority: Major
>
> I'm using ApacheDS, I found this problem and am not sure if it's a mina issue 
> or an ApacheDS issue.
>  
> AbstractPollingIoProcessor#read looks like this:
>  
> {code:java}
> private void read(S session) {
>     IoSessionConfig config = session.getConfig();
>     int bufferSize = config.getReadBufferSize();
>     IoBuffer buf = IoBuffer.allocate(bufferSize);
>     final boolean hasFragmentation = 
> session.getTransportMetadata().hasFragmentation();
>     try {
>         /* omitted */
>         if (ret < 0) {
>             IoFilterChain filterChain = session.getFilterChain();
>             filterChain.fireInputClosed();
>         }
>     } catch (Exception e) {
>         if ((e instanceof IOException) &&
> (!(e instanceof PortUnreachableException)
> || !AbstractDatagramSessionConfig.class.isAssignableFrom(config.getClass())
> || ((AbstractDatagramSessionConfig) config).isCloseOnPortUnreachable())) {
>             scheduleRemove(session);
>         }
>         IoFilterChain filterChain = session.getFilterChain();
>         filterChain.fireExceptionCaught(e);
>     }
> }
> {code}
>  
> When an exception occurs with an LDAP connection, e.g. Connection reset by 
> peer, catch block is entered and ExcpetionCaught gets fired:
> {code:java}
> filterChain.fireExceptionCaught(e);{code}
> The session is thus closed by LdapProtocolHandler#exceptionCaught:
> {code:java}
> public void exceptionCaught( IoSession session, Throwable cause )
> {
>     if ( cause.getCause() instanceof ResponseCarryingMessageException )
>     {
>         ResponseCarryingMessageException rcme = ( 
> ResponseCarryingMessageException ) cause.getCause();
>         if ( rcme.getResponse() != null )
>         {
>             session.write( rcme.getResponse() );
>             return;
>         }
>     }
>     LOG.warn( "Unexpected exception forcing session to close: sending 
> disconnect notice to client.", cause );
>     session.write( NoticeOfDisconnect.PROTOCOLERROR );
>     LdapSession ldapSession = 
> this.ldapServer.getLdapSessionManager().removeLdapSession( session );
>     cleanUpSession( ldapSession );
>     session.close( true );
> }
> {code}
> Although this session is scheduled for removal, due to its state being 
> closing, AbstractPollingIoProcessor#removeSessions does nothing about this 
> session:
> {code:java}
> case CLOSING:
>     // Skip if channel is already closed
>     // In any case, remove the session from the queue
>     removedSessions++;
>     break;
> {code}
> Consequence is that this session is kept forever in 
> IoServiceListenerSupport.managedSessions, and as its size grows, this 
> ConcurrentMap can take up quite a large amount of memory.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to