This is still an issue as of 1.16.2. It also seems to have migrated to MC-183518 with additional information. It doesn't appear to be getting traction there either. I'm surprised considering how many MC servers are hosted on VPS. At the end of the day, it's just under $20 USD per year in wasted electricity for me, and having one fewer core to borrow idle time from in my host. In the meantime, I posted information in the comments on the above-linked issue.
I've been running a vanilla Minecraft server with no add-ons for many years, and I can confirm that this issue is still present in 1.16.2. Because so many Minecraft servers are hosted on virtual private servers, this issue seems fairly serious. I have tested this with a KVM hypervisor running Debian 10 and a guest running Debian 10 (CLI only) with 6GB of RAM dedicated to it. I tried:
Setting the vCPU allocation to 1, 2, and 3 in separate tests;
Setting the ethernet interface as Virtio or e1000 in separate tests;
Changing between ePoll and default channel types (use-native-transport in server.properties);
Changing various clock sources in the guest.
Note on that last bullet point that the host is using TSC as its clock source. The guest, as is expected, locks out TSC as unstable and uses kvm-clock (preferred), hpet, acpi-pm, etc. instead. Without native TSC, all other clock sources are virtualized which, I believe, involves context switching to the hypervisor for timing inquiries.
While I don't understand the structure of Minecraft server under the hood, I would expect that if it uses spin-waits that involve timer checks, it may result in a ton of context switching to the hypervisor to service those. This could possibly be overcome by estimating the typical time each cycle of the spin takes and spinning a certain number of times between clock checks to minimize the context switching while delivering a reasonably high degree of timing accuracy.
These images were taken from a completely idle 1.16.2 instance a few minutes after it completed its start-up.
[media]Information from "top" as seen from the guest running an idle Minecraft server. The java process is shown.
[media]
Information from "virt-top" as seen from the host. The subject guest is shown.
[media]
Information from "top" as seen from the host. The subject guest process is shown.
Note that this appears to be the same or related to the issue listed in MC-154629, which a bot claimed was resolved but appears to have not been.
To the developers: Thank you for your time looking into this issue.
Thanks to Michael Meier's additional information and workaround, I tried some related configuration changes. It doesn't solve the problem entirely, but using a stock Debian 4.19 kernel, I added the following two kernel configuration parameters in the Grub bootloader on the guest that runs Minecraft: nohz=off highres=off
I don't see a kernel parameter to drop the periodic tick to 100Hz from the Debian default of 250Hz.
However, just this change dropped the idle server from holding a core at 100% down to roughly 8% utilization. The game server seemed to run fine, although more testing is needed. It's still not a perfect fix, but this might be the easiest "fix" for a while.
This should work with other recent kernels and other Linux distributions, but I haven't tested on any other setups.