-
-
Notifications
You must be signed in to change notification settings - Fork 16.3k
io.netty.channel.socket.nio.AbstractNioWorker.run() using 100% CPU #302
Description
I noticed there is an "infinite" for (;;) and this is what is causing 25% cpu usage on a quad core for me, while my client is waiting for messages to be received. It's not excluded that I might be missing something here, but at the time of this writing I am not aware of it.
I did a small test by putting Thread.sleep(100); before "SelectorUtil.select(selector);" line, and the cpu usage went down to 0 % more or less but thiis is doesn't seem to be the way to fix this (unless at the very least catching+ignoring InterruptedException).
There is a comment block right after that line, though I can't pretend to understand what it means:
"
// 'wakenUp.compareAndSet(false, true)' is always evaluated
// before calling 'selector.wakeup()' to reduce the wake-up
// overhead. (Selector.wakeup() is an expensive operation.)
//
// However, there is a race condition in this approach.
// The race condition is triggered when 'wakenUp' is set to
// true too early.
//
// 'wakenUp' is set to true too early if:
// 1) Selector is waken up between 'wakenUp.set(false)' and
// 'selector.select(...)'. (BAD)
// 2) Selector is waken up between 'selector.select(...)' and
// 'if (wakenUp.get()) { ... }'. (OK)
//
// In the first case, 'wakenUp' is set to true and the
// following 'selector.select(...)' will wake up immediately.
// Until 'wakenUp' is set to false again in the next round,
// 'wakenUp.compareAndSet(false, true)' will fail, and therefore
// any attempt to wake up the Selector will fail, too, causing
// the following 'selector.select(...)' call to block
// unnecessarily.
//
// To fix this problem, we wake up the selector again if wakenUp
// is true immediately after selector.select(...).
// It is inefficient in that it wakes up the selector for both
// the first case (BAD - wake-up required) and the second case
// (OK - no wake-up required).
"