You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Wenxiang Qiu (JIRA)" <ji...@apache.org> on 2018/06/04 09:02:00 UTC
[jira] [Created] (DIRMINA-1086) IoSessions closed by
filterChain.fireExceptionCaught(e) are kept in memory
Wenxiang Qiu created DIRMINA-1086:
-------------------------------------
Summary: 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
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, i.e. 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)