Netty работает на 100% CPU

Я видел другие ссылки на эту проблему, такие как здесь и здесь, хотя эта ссылка разные версии Netty. Пробовал это, используя последние в ветке 4.0 (4.0.29) и в ветке 5.0 alpha (5.0-Alpha3). Локальный (не linux) jdk 1.8.040, отлично. Удаленный (Linux) с java jdk 1.8.025-b17 получает 100% -ный процессор. Ядро Linux 2.6.32.

Пробовал использовать EpollEventLoopGroup();

Пробовал вызов

workerGroup = new NioEventLoopGroup();
workerGroup.rebuildSelectors();

Кто-нибудь может предложить какие-либо предложения? Я видел ссылки на эту ошибку с различными версиями Netty. Ошибка Jdk? Ошибка Netty? Процесс переходит на 100% сразу при запуске и остается там.

Обновление: обновлено до версии 1.8.045, с той же разницей.

JStack output всех запущенных потоков (там есть некоторые вещи кролика, только включенные для полноты, которые являются общими для других приложений, и это не является причиной проблемы).

Ответ 1

Как мы отметили в комментариях, поток, потребляющий процессор, занят в следующем стеке:

"pool-9-thread-1" #49 prio=5 os_prio=0 tid=0x00007ffd508e8000 nid=0x3a0c runnable [0x00007ffd188b6000]
   java.lang.Thread.State: RUNNABLE
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Мне удалось воспроизвести аналогичное поведение, создав ScheduledThreadPoolExecutor, сконфигурировав его, чтобы разрешить тайм-ауты ядра и планировать множество повторяющихся задач с небольшой задержкой. Это дает много процессора на моей машине, а вывод jstack аналогичен (иногда глубже в методе poll). Этот код воспроизводит его:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.setKeepAliveTime(1, TimeUnit.MINUTES);
executor.allowCoreThreadTimeOut(true);
for (long i = 0; i < 1000; i++) {
    executor.scheduleAtFixedRate(new Runnable() {

        @Override
        public void run() {
        }
    }, 0, 1, TimeUnit.NANOSECONDS);
}

Теперь нам нужно определить, какой код устанавливает сломанный ScheduledThreadPoolExecutor. Я искал исходный код RabbitMQ и Netty, не найдя ничего obvoius. Может быть, это то, что вы делаете в своем собственном коде?

Изменить. Как упоминалось в комментариях, основной причиной было ScheduledThreadPoolExecutor, инициализированное с помощью 0, которое, по-видимому, может вызвать переключение CPU на некоторые платформы. Это было сделано в OP-коде.