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