[
https://issues.apache.org/jira/browse/SSHD-854?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16674658#comment-16674658
]
jpalacios commented on SSHD-854:
--------------------------------
Hi [~elecharny],
Thank you for getting back to me.
{quote}First, check the logs you should see messages like ' Create a new
selector. Selected is 0, delta = XXX'.
{quote}
Unfortunately this is not possible. Bitbucket Server sets logging of
{{org.apache.mina.core.service.IoProcessor}} to {{ERROR}} so the messages will
not be present. However in the heap dump I can see multiple
{{SelectionKeyImpl}} instances referencing the same {{NioSocketSession}}
instance. As I said, there are {{382976}} instances of {{SelectionKeyImpl}} and
only 94026 {{NioSocketSession}} instances. Wouldn't you say that indicates that
the selector is being replaced and new keys are being generated?
{quote}The new selector will just use the registered {{SelectionKey}} from the
old selector
{quote}
Are you sure this is correct? AFAICT it isn't. {{NioProcessor}} will register
the new instance of the selector with the channel and it will get a new key:
{code:java}
SelectionKey newKey = ch.register(newSelector, key.interestOps(), session);
{code}
This is the implementation of {{AbstractSelectableChannel.register}}:
{code:java}
public final SelectionKey register(Selector sel, int ops,
Object att)
throws ClosedChannelException
{
synchronized (regLock) {
if (!isOpen())
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException();
if (blocking)
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
k.interestOps(ops);
k.attach(att);
}
if (k == null) {
// New registration
synchronized (keyLock) {
if (!isOpen())
throw new ClosedChannelException();
k = ((AbstractSelector)sel).register(this, ops, att);
addKey(k);
}
}
return k;
}
}
{code}
And this is how {{findKey}} works:
{code:java}
private SelectionKey findKey(Selector sel) {
synchronized (keyLock) {
if (keys == null)
return null;
for (int i = 0; i < keys.length; i++)
if ((keys[i] != null) && (keys[i].selector() == sel))
return keys[i];
return null;
}
}
{code}
As you can see, when using a new instance of the selector, {{findKey}} will
return {{null}} because {{keys[i].selector() == sel}} *cannot* be {{true}}.
Leter when {{((AbstractSelector)sel).register(this, ops, att)}} is called a new
instance of {{SelectionKeyImpl}} is created:
{code:java}
protected final SelectionKey register(AbstractSelectableChannel var1, int
var2, Object var3) {
if (!(var1 instanceof SelChImpl)) {
throw new IllegalSelectorException();
} else {
SelectionKeyImpl var4 = new SelectionKeyImpl((SelChImpl)var1, this);
var4.attach(var3);
Set var5 = this.publicKeys;
synchronized(this.publicKeys) {
this.implRegister(var4);
}
var4.interestOps(var2);
return var4;
}
}
{code}
{quote}Once the old selector is closed, it does not retain references to
selection keys.
{quote}
This is not actually what happens. As it was also pointed out in DIRMINA-1042,
{{EPollSelectorImpl}} will not clear the {{fdToKey}} map so all the keys there
will still be referenced.
Looking forward to hearing your thoughts
Juan Palacios.
> Massive object graph in NioSocketSession
> ----------------------------------------
>
> Key: SSHD-854
> URL: https://issues.apache.org/jira/browse/SSHD-854
> Project: MINA SSHD
> Issue Type: Bug
> Reporter: jpalacios
> Priority: Major
>
> I'm looking at a heap dump from one of our customers where the retained heap
> size for some {{NioSocketSession}} instances is almost 1GB.
> From the looks of the dump MINA has created a massive object graph where:
> {code}
> NioSocketSession -> SelectionKeyImpl -> EpollSelectorImpl -> HashMap ->
> SelectionKeyImpl -> NioSocketSession -> ...
> {code}
> From the looks of the obeject IDs these are not loops
> Each individual object is not large by itself but at the top of the graph the
> accumulated retained size is enough to produce an OOME
> Could you help me understand how MINA can produce such a massive object
> graph? Should MINA apply any defense mechanism to prevent this??
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)