I have some additional information that may be helpful, as well as a hack that can be used without recompiling the kernel or tweaking boot parameters.
I'm experiencing the same high CPU while idling problem on a 1.19 based modpack. The server is running directly on the host, so no VM involved in this case.
As Michael Meier described, I also observe a high number of syscalls, mainly:
clock_gettime
futex (with a timeout 1 microsecond from the time returned by clock_gettime)
futex (apparently to signal/wake up something else after the first futex)
Using the spark profiler in Minecraft, it seems like it's trying to sleep (using parkNanos) while waiting for the next event, but tracing the syscalls reveals that it appears to be using a very low timeout. This probably doesn't hurt much on Windows, but Linux has higher precision timers by default and will return more quickly. What looks like a reasonable wait on Windows effectively turns into a busy loop / spin on Linux with a tiny sleep that hides the problem slightly: I observe about 35% CPU (of a core) on the most offending thread instead of the 100% that would have clearly labelled this as a busy loop.
The problem here is not Linux, it's just that Windows (and probably also FreeBSD) doesn't expose a timeout that appears to be set way too low.
I came across this blog post that examines parkNanos and provided a simple way to tweak the Java process (and threads):
Checking on my host, I have the same value of 50000 (50 microseconds) in /proc/pid/timerslack_ns. Using jstack to find the Java threads waiting on parkNanos, and setting timerslack_ns to a higher value for those threads significantly reduced the CPU load on my computer.
Since there are many threads, I made a quick hack in Python to find the Java threads belonging to the Minecraft server and set their timerslack to 5ms:
With no users on, I went from around 50% CPU usage in total (35% from the main thread, the rest from a few other threads) to around 4-7% CPU usage on the host.
Hi,
I have some additional information that may be helpful, as well as a hack that can be used without recompiling the kernel or tweaking boot parameters.
I'm experiencing the same high CPU while idling problem on a 1.19 based modpack. The server is running directly on the host, so no VM involved in this case.
As Michael Meier described, I also observe a high number of syscalls, mainly:
clock_gettime
futex (with a timeout 1 microsecond from the time returned by clock_gettime)
futex (apparently to signal/wake up something else after the first futex)
Using the spark profiler in Minecraft, it seems like it's trying to sleep (using parkNanos) while waiting for the next event, but tracing the syscalls reveals that it appears to be using a very low timeout. This probably doesn't hurt much on Windows, but Linux has higher precision timers by default and will return more quickly. What looks like a reasonable wait on Windows effectively turns into a busy loop / spin on Linux with a tiny sleep that hides the problem slightly: I observe about 35% CPU (of a core) on the most offending thread instead of the 100% that would have clearly labelled this as a busy loop.
The problem here is not Linux, it's just that Windows (and probably also FreeBSD) doesn't expose a timeout that appears to be set way too low.
I came across this blog post that examines parkNanos and provided a simple way to tweak the Java process (and threads):
https://hazelcast.com/blog/locksupport-parknanos-under-the-hood-and-the-curious-case-of-parking/
Checking on my host, I have the same value of 50000 (50 microseconds) in /proc/pid/timerslack_ns. Using jstack to find the Java threads waiting on parkNanos, and setting timerslack_ns to a higher value for those threads significantly reduced the CPU load on my computer.
Since there are many threads, I made a quick hack in Python to find the Java threads belonging to the Minecraft server and set their timerslack to 5ms:
https://gist.github.com/jmbjorndalen/23e6922b8ef069014463ffc97d717506
With no users on, I went from around 50% CPU usage in total (35% from the main thread, the rest from a few other threads) to around 4-7% CPU usage on the host.
If you are curious, there is also a blog post that examines parkNanos on Windows:
https://dzone.com/articles/locksupportparknanos-under-the-hood-and-the-curiou