0

I have SocketChannel configured for read only SelectionKey.OP_CONNECT | SelectionKey.OP_READ Profiler shows runChannel is the most CPU consuming method and actually it is reasonable because it's infinite loop which calls method selector.select() all the time, but on the other hand I have dozens of such connections and it kills CPU.
Is there a possibility to decrease CPU load and in the same time do not miss any incoming message?

public void runChannel() {
    while (session.isConnectionAlive()) {
        try {
            // Wait for an event
            int num = selector.select();
            // If you don't have any activity, loop around and wait
            // again.
            if (num == 0) {
                continue;
            }
        } catch (IOException e) {
            log.error("Selector error: {}", e.toString());
            log.debug("Stacktrace: ", e);
            session.closeConnection();
            break;
        }
        handleSelectorkeys(selector.selectedKeys());
    }

}

Dimitar
  • 4,402
  • 4
  • 31
  • 47
Diyko
  • 388
  • 1
  • 8
  • 28
  • sleep(0) in the loop? – Tokazio Mar 31 '16 at 14:19
  • What JRE and OS version are you using? Next - this method is implemented where? You should have only a single thread selector loop. Is it so? Are all data read when available? Is there are reason you wait for connect and read? (you should use only the appropriate one) – gusto2 Mar 31 '16 at 14:36
  • JRE 7, I tried on different version of windows (server for prod, win7 for dev) – Diyko Mar 31 '16 at 14:38
  • After some searchig - you are registering for OP_CONNECT and OP_READ at the same time. It may cause problems. There is nothing to read until OP_CONNECT has fired. Just register for OP_CONNECT at first and OP_READ when connected – gusto2 Mar 31 '16 at 14:41
  • I will try I dont see reason actually – Diyko Mar 31 '16 at 14:49
  • sleep(0) and yeild doesnt work – Diyko Mar 31 '16 at 14:50
  • Without OP_CONNECT channel doesnt read messages at all – Diyko Mar 31 '16 at 15:09
  • I meant to use only OP_CONNECT and when connected, switch to OP_READ. – gusto2 Mar 31 '16 at 16:29
  • What profiler do you use? Most Java profilers will show long-running native methods as CPU consuming, even if they are not. Just because JVM does not distinguish a busy native method from a method sleeping inside a system call. – apangin Mar 31 '16 at 17:48
  • @Tokazio He is calling `select()` in the loop, which blocks until something happens. Sleeps in networking code are just cargo-cult programming. – user207421 Mar 31 '16 at 22:44

1 Answers1

1

Unsunscribe from OP_CONNECT - select() won't block if you're subscribed to OP_CONNECT and connected.

mvmn
  • 3,717
  • 27
  • 30
  • 1
    And ditto OP_WRITE, which should only be used when you have filled the socket send buffer and `write()` has returned zero. – user207421 Mar 31 '16 at 22:47