15

I have a minecraft server (1.16.5) hosted on a VPS that has 16 GB of ram, I play with 8 friends on the server and it is using all of my ram, we play vanilla survival, but I don't see how this can cause the server to use 12 GB of ram.

The startup command is:

java -Xms14G -Xmx14G -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=50 -XX:+DisableExplicitGC -XX:TargetSurvivorRatio=90 -XX:G1NewSizePercent=50 -XX:G1MaxNewSizePercent=80 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1MixedGCLiveThresholdPercent=50 -XX:+AggressiveOpts -jar server.jar

I am using paper which has helped a ton with performance, and have configured some options on the bukkit.yml, spigot.yml, paper.yml and the server.properties.

Any reason for my server to be using this much ram?

4
  • 3
    as an aside - where did you get these settings from? Its possible these settings are meant for someone with a different, specific config. Commented Feb 11, 2021 at 7:43
  • I was looking at a /timings paste and it showed me that it had outdated flags, so I copied the arguments that they had put in that post and tweaked some of it
    – Mark_Ed
    Commented Feb 11, 2021 at 9:01
  • 1
    How fast does it get to 100%? JVM is notorious for mem leaks.
    – blankip
    Commented Feb 11, 2021 at 20:16
  • After 5 minutes of the server being online it will be at 100%
    – Mark_Ed
    Commented Feb 11, 2021 at 23:02

2 Answers 2

54

You're setting these two options:

-Xms14G -Xmx14G

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 -Xms and -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:

-Xlog:gc*:gc.log:time,level,tags:filecount=5,filesize=1024K

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.

So:

  • 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.

4
  • 1
    Wow, thank you for such a detailed answer, this really made things clear, I am still using Java 8 since I am using Pterodactyl panel and don't really know how to update that yet, will have to figure that out so I will use the Java 8 options first. I will get back to you if I need any more help.
    – Mark_Ed
    Commented Feb 10, 2021 at 23:42
  • The heap hovers between 3.5GB and 4.5GB.Which after GC Makes it between 1GB to 1.5GB. Now that I have lowered the allocated GB's to 8 it still appears to use 100% of that. If anything changes in the next couple of hours I'll come back to this.
    – Mark_Ed
    Commented Feb 11, 2021 at 14:57
  • 1
    @Mark_Ed: If you set -Xms and -Xmx to the same number, then that is the expected behavior. It will always use at least the -Xms number once it's managed to actually fill up that much memory at least once, because that's what -Xms means: "Please use at least this much memory."
    – Kevin
    Commented Feb 12, 2021 at 19:46
  • @Kevin not quite right Xms is only starting heap size, it's NOT "use at least this much memory". Memory can be "uncommited" by GC, the heap can still be decreased. If you want to disable this behaviour use shoud use -XX:-AdaptiveSizePolicy P.S. this works best with -XX:+AlwaysPreTouch to avoid problems with linux not allocating physical memory right ahead and prevent from the possible problems in fail-fast style. Commented Feb 12, 2021 at 21:06
6

One of the JVM arguments has me concerned - -XX:+DisableExplicitGC.

Minecraft-Java Servers are Java based, and thus run in a Java Virtual Machine (JVM). The arguments you supply in your startup command tell the JVM how to operate, with what configuration, etc.

According to Oracle Documentation (Oracle owns Java):

Use -XX:+DisableExplicitGC to disable calls to System.gc(). Note that the JVM still performs garbage collection when necessary.

By supplying this argument, you are telling the JVM for your server to disable system Garbage Collection. Without getting too detailed, the Garbage Collector manages the memory of a Java program automatically. As the quote says, it will still perform garbage collection as needed, but it appears to not need to in your case (maybe because you still have ~2Gb or RAM to spare, based off of your Xmx argument). One source says that by setting this, it could be delaying garbage collection events for longer times.

Thus, I would try changing the argument to -XX:-DisableExplicitGC or maybe just remove it outright.

6
  • Comments are not for extended discussion; this conversation has been moved to chat. Commented Feb 11, 2021 at 18:30
  • I doubt Minecraft calls System.gc to begin with. The option shouldn't be dangerous. Commented Feb 12, 2021 at 12:08
  • 2
    @user253751 explanation why this option is dangerous is in the chat above, otherwise it's groundless theorizing. In short JVM uses explicit gc calls internally, and there's also direct memory which limit is equal to xmx(14 gb in this case), it's not limited only with heap and class space. The part with wrong wording is that it disables system gc - it really delays system gc but it still leads to OOM kill. Commented Feb 12, 2021 at 14:45
  • 8
    "By supplying this argument, you are telling the JVM for your server to disable system Garbage Collection." Wrong, you are telling the JVM to ignore when Minecraft wants to GC. When the JVM want to GC, it will anyways. Commented Feb 12, 2021 at 14:51
  • 1
    Yes, this wording is incorrect(but there s citation Note that the JVM still performs garbage collection when necessary.) , but the solution is in fact correct, one should never disable explicit GC in server environment - if you really want to stop GC then use noop collector. Commented Feb 12, 2021 at 14:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .