On 10/11/06, Alessandro Torrisi <[EMAIL PROTECTED]> wrote:

Now I have some more time and I want to optimize it. The core seems to be
quite stable, but I have memory and cpu problems.


Good to hear that MINA is stable!  Now let's see what problem you've got.

I'm trying in all the ways to optimize it and a lot of times I tryied to
change the design of the application.
I can say in the last month I gave it a great speed up, but it's not
sufficient.

The software reaches a 1000 users number. The problem is that after a few
minutes (10, 20 minutes) the performance takes down in a bad way. Memory
usage is too high, cpu usage also.

I want to optimize object usage, verify if my design pattern is right or
could be better, try to implement some filters (for example for throttling
-
I thought to a filter which suspends the client from writing and reading
for
a while, then resume all the operations).

I can describe my application in this way:

1) Users are created when sessions are opened (User is a POJO object), it
is
stored in IoSession through the setAttribute("user", myUserInstance). The
user object contains all the informations I need for the communication
(nick, description, email, connection speed, etc).
Every nick is the key of a ConcurrentHashMap<String, IoSession>, which is
important for me to take the session given a nick (many protocols commands
say for example "send to Nick this", or "connect to Nick" and more... and
I
have to get a user by his nick)...Is a ConcurrentHashMap convenient ?
Ideas
? Is it optimized according to you ?


I think ConcurrentHashMap is good enough for general usage, and seeking a
session with a peer name (nickname in this case) is a common technique.

2) I have implemented a DCProtocolHandler which extends IoHandlerAdapter.
This instance of ProtocolHandler has a unique DCPipeline instance, and the
pipeline has a dispatch method called "dispatchAction", this method checks
what command is and passes it to a private method which runs the necessary
code to satisfy the request.
Is this way the right choice ?


Sure.  You could also take a look into DemuxingIoHandler.

3) To return back to the clients the answers I use a "Sender" class which
has static methods (for example sendData, sendDataToAll, send...) for
every
answer I call Sender.sendData(message)... etc


I see.

In short:

    public static void sendData(IoSession session, String message) {
        if (!message.endsWith(C_END_CMD))
            message += C_END_CMD;
        ByteBuffer wb = ByteBuffer.allocate(message.getBytes().length,
true);
        try {
            wb.putString(message, encoderCp1252);
        } catch (CharacterCodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        wb.flip();
        if (null != session && session.isConnected()) {
            session.write(wb);
        }
    }

or

    public static void sendDataToAll(String message) {
        if (!message.endsWith(C_END_CMD))
            message += C_END_CMD;
        ByteBuffer wb = ByteBuffer.allocate(message.getBytes().length,
true);
        try {
            wb.putString(message, encoderCp1252);
        } catch (CharacterCodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        wb.flip();
        Collection<IoSession> sessions = DCServer.getUserList().values();
        for (IoSession currSession : sessions) {
            currSession.write(wb.duplicate());
        }
    }

Static methods called in this way are good ? And then the byte buffer
allocation in this way is right ?


Using static method cannot be a problem.  It's entirely up to you whether to
use static methods or not.

Calling message.getBytes() to calculate the buffer length is not a good idea
in this case because the call generates an extra byte array.  You can get
the array and use ByteBuffer.put(byte[]) rather than calling putString,
which causes another string-to-bytes conversion.

This is the big (little) picture. I have to understand many things of mina,
for example what's the difference between a direct buffer or a simple byte
buffer ? What is the best way to send a message to many sockets
(IoSession)


The question on the difference between a direct buffer and a heap buffer
belongs to general NIO questions.  Please refer to your NIO tutorial or
JavaDoc.  It seems like direct buffer management in nowadays JVM is not
robust enough in some cases.  Please try to switch to heap buffers if direct
buffers are not being released fast enough.  The best way is to use
broadcast, but it doesn't support guarenteed delivery.  You could take a
look into other open source projects for group messaging:

  - JGroups <http://www.jgroups.org/javagroupsnew/docs/index.html>
  - Appia <http://appia.di.fc.ul.pt/wiki/index.php?title=Main_Page>

Basically, duplicating a buffer and writing them to each sessions should
work fine.  To reduce total memory consumption, you could use a queue to
prevent too many buffers are allocated during the short period.

When I have to suspend and resume operations (not implemented and never
tryied) ?


It depends on what you want and is completely application-dependent.

If someone wants to read the code can access CVS or download the latest
version from sourceforge, more appreciated is a project collaboration
(!!!)


Our source code is always available here (It's a Subversion repository):

http://svn.apache.org/repos/asf/directory/trunks/mina/

HTH,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Reply via email to