You're setting these two options:
This means that the JVM should start with 14 GB (-Xms) and grow to a maximum of 14 GB (-Xmx) heap RAM usage. The actual RAM usage will be higher, as java needs some space for itself, for loaded classes, for garbage collection temporary internals, etc. Which in turn means the JVM will allocate close to 16 GB right from the start.
Now, on a Linux system, this will not physically allocate all 14 GB heap right at start - the JVM asks Linux to allocate 14 GB, Linux tells the JVM "here you go", but those ram pages will only get assigned to the JVM once they get written. It'll take anywhere from several seconds to 1-2 hours of playing time until the JVM actually writes to all the RAM, so up to that point, the OS will at least have some of the RAM to itself. Once the 14 GB are filled up, Java will start its first garbage collection - so it will release a lot of memory internally, but won't give that memory back to your system.
Which means your Linux is very low on disk cache, which means a lot more disk access than necessary, which generally means a lot of lag. (This might be somewhat better on a VPS where disk access goes through the host which might have some cache itself).
What you really should do is lower your
-Xmx parameters to half of the available RAM, which would be 8 GB in your case. Then, check how much RAM your Minecraft really needs, by turning on GC logging and checking the log files.
For Java 14 (which you should be using together with Paper), add this to your java invocation:
This will generate a file named
gc.log in your server directory (plus, over time, a few older generations named
gc.log.0 and so on. Those files have information about every GC run, the interesting lines are the ones that look like this:
Pause Young (Normal) (G1 Evacuation Pause) 10247M->2108M(16384M) 9.477ms
In this case, the -Xmx parameter was
16G, this is where the
16484M comes from. Garbage collection started running when 10247 MB were used, and ended up with 2108 MB after the garbage collection. Which means that you absolutely can't go below ~ 2 GB because that's what Java really needs, and shouldn't go below around double this value. Everything above, in my case, 4 GB, is luxury that you can spend if you have it, but won't help you much, and may actually be harmful because it eats into the system's disk cache.
- set your memory parameters to 8 GB
- turn on GC logging, play for a day, and check how much heap the server really needs after garbage collection
- assign 2-3 times this value to -Xmx, and this value to -Xms
- if you need a lot less than the 2 GB of my case, you can still go up to half the maximum amount of what the VPS has; 8 GB in your case
- if you need a lot more, say, you need 8 GB after garbage collection (which should only happen if you have a ton of plugins or several misbehaved ones), increase the RAM of your VPS to approx. 3-4 times the value after garbage collection, and still set -Xmx to half your available RAM/twice the value needed after GC.
If you're still using Java 8, the startup options change to
-verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=1M
and the log file entries will look more like this:
[Eden: 8176.0M(8176.0M)->0.0B(8176.0M) Survivors: 16.0M->16.0M Heap: 10.7G(16.0G)->2790.4M(16.0G)]
In this case, it's the
Heap value you're interested in: here, 16 GB from
-Xmx, 10.7GB used before GC, 2790 MB after GC.