Le 3/22/13 7:46 AM, 马学祥 a écrit :
> Dear all,
Hi !
>
> I'm using mina 2.0.4 as a framework of one game server,some day the server 
> occured memory leak. By using MAT to analyse the jvm dump, i founded the 
> memory 
> leak creater is the
> NioSocketSession.Two NioSocketSession consume about 3.5GB memory,at this 
> time, 
> the total online user was 150, but just two of them occured memory leak,and 
> other server whose online user was higher works well.Can somebody know what's 
> the reason or How can i fix the reason? 
First of all, no, there is no memory leak in Mina - AFAICT -. There are
*many* reasons why you may get a memory issue though.

Looking at the screenshot you sent, I can imagine a very simple scenario
where a queue of message waiting for being sent can grow up to a point
it saturate your memory. Imagine a server which generate a loooong
response (or many small ones). Imagine a client which is not anymore
connected after having sent its original request, or a client which is
very sloooow to read it's message : all the messages will be stacked on
the write queue, waiting for the client to read them.

How to avoid such a scenario ?
Two possibilities : one defensive, one pro-active.

1) Defensive

You have to deal with disconnected clients. The only way is either to
use KeepAlive (which is not always possible), or manage session idling.
After a certain delay, the session is considered as dead, and your
application just close it, removing all the messages in its write queue.

2) Pro-active

A defensive mechanism is not enough. You may want to control the number
and size of messages you sent. The best solution - but it's not easy to
implement - is to wait for each previous message to have been sent to
the client before sending a new one. A message is sent when the
IoHandler receive the messageSent event. You can trap it and use it to
send the next message.

A typical situation would be when you send back many elements as a
response to a request (imagine you are asked for a selection of
elements, and this selection contains 10 000 elements, which will be
sent one by one). What you do in the IoHandler.messageReceived() method
is that you send the first element, and store the way to get the next
element sin the session context. Then when the first message has been
sent (I mean, *really* sent, not just enqueued in the server), you will
get a messageSent() event, and in the IoHandler.messageSent() event, you
fetch the next element using the data stored into your session context,
and you are done for this element. Of course, you will be called back
again, and again, until the last element has been sent.

Thekey here is that you are in control. You dont accumulate anything in
memory, nor do you block a thread for ever. Obviously, this requires
more code, and you msut be sure you don't gather all the elements in
memory before sending them to the client, otherwise it defeats the whole
logic...

I hope I clarified the way your code should work.

One last thing : You *have* to migrate to 2.0.7. It contains various bug
fixes.

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com 

Reply via email to