Skip to content

Instantly share code, notes, and snippets.

@youmukonpaku1337
Last active March 2, 2023 18:39
Show Gist options
  • Save youmukonpaku1337/cd835fbac39c0c446006250df010d7ca to your computer and use it in GitHub Desktop.
Save youmukonpaku1337/cd835fbac39c0c446006250df010d7ca to your computer and use it in GitHub Desktop.

Minecraft 2nd stage optimization (after installing optimization mods)

I've been hosting a minecraft server for about 2 months now, and as every fabric server owner I like optimization, and a lot of it.
For servers I have tried the Shenandoah, C4, ZGC, Shenandoah IU, Shenandoah Generational and the G1 garbage collectors mainly serverside, but I did some clientside testing too.
All of them except G1GC sucked, and I've determined that by normal usage and a test of mine.

Testing

The test I've tried:

  1. Spawn about 20 players with carpet's /player command,
  2. Then, run /spreadplayers 0 0 1000 10000 false @a to spread players in a 10k block radius around the world

Results

Shenandoah and ZGC

With Shenandoah, Shenandoah Generational and ZGC Minecraft spread the players, and the tps dropped to 10, and went down until 1.

G1

With G1 it dropped to 17-18 for about half a minute then stabilized at 20.

Test Accuracy

The test might be inaccurate and inconsistent in some cases, don't take it too seriously, it's just an example

GC pauses

ZGC and Shenandoah

ZGC and Shenandoah/Shenandoah Generational took 2 seconds to GC every time.

G1

G1 took 10-60ms for every GC. (both were measured with spark gcmonitor)

Specs

CPU

Intel Xeon E5-2698 v4 with 16 threads (because I was using a QEMU/KVM VM)

RAM

16GB RAM

Storage

350GB HDD storage for server (irrelevant)

GPU

none

TPS, MSPT and CPU usage

From a simple spark healthreport, here are the results I get with:

G1GC

Average MSPT: 28
TPS: 20
CPU usage: 4-5%

Shenandoah, ZGC and Shenandoah Generational

Average MSPT: 20-30 (apparently MSPT isn't locked to TPS, as ishland from the RelativityMC server told me)
TPS: 1.96
CPU usage: 55-60% because of extremely frequent and slow GCs

Mods installed while testing

I'm doing these tests in my main env, which is the server for the SuperCharged modpack.
Modlist: https://webducky.cf/kat/modlist.txt

JVM flags for tests

G1GC

For G1GC I have used my flags which are Aikar's stripped of G1 heap settings which worsen performance on some devices + G1 tweaks itself anyway.

ZGC

On ZGC I used -XX:ConcGCThreads=4 however performance is the same without it

Shenandoah, Shenandoah IU and Shenandoah Generational

On ShenandoahGC I used ShenandoahGC only and hilltty's flags, I have also tested Shenandoah Generational, all performed about the same.

Do note that I'm not saying ShenandoahGC or ZGC are bad, but on most setups they might not work well, while G1 is almost universal.

Alternative memory allocators to improve performance

Jemalloc

Fast and prevents memory leaks.
I provide an env var for jemalloc with these flags, which enables the background thread it runs on and also improves speed

tcmalloc and mimalloc

Might be faster than Jemalloc, however might have more memory leaks, no configuration env var

Guide for optimization

Client, mainly Singleplayer

Steps

  1. First of all, you'd want to install the Corretto or Zulu JDK or JRE, and make your Minecraft launcher of choice use the JDK/JRE you installed. Downloads for Zulu (DO NOT USE PRIME): https://www.azul.com/downloads/ and downloads for Corretto: https://aws.amazon.com/corretto/
  2. (For Linux only) Also, install jemalloc and gamemoderun (feral-gamemode), go to launcher options and set wrapper command to env LD_PRELOAD=/usr/lib/libjemalloc.so MALLOC_CONF=abort_conf:true,background_thread:true,narenas:4,dirty_decay_ms:1000,muzzy_decay_ms:1000 gamemoderun
    2.1. Change the 4 in narenas:4 to the amount of threads on your machine
  3. Then, you'd want to set the allowed memory of MC to 4-6GB if you only have 8GB of RAM on host, and 8-12GB if you have 16GB of RAM on host (make sure to NOT give Minecraft more than 12GB of RAM on G1 heaps).
  4. Afterwards, set your Java flags to -XX:+PerfDisableSharedMem -XX:+UseStringDeduplication
    Note: make sure to not run any heavy programs besides MC when playing, e.g. another game

Client, mainly Multiplayer

Steps

  1. Install the IBM Semeru runtime, which includes OpenJ9 here https://developer.ibm.com/languages/java/semeru-runtimes/downloads/
  2. Follow step 2 (if on Linux) and 3 of the guide for Singleplayer (about 4GB is recommended, more than that helps only a bit)
  3. Set Java flags to -Xshareclasses:bootClassesOnly
    It's fine to run other programs other than MC, just make sure it's not a lot and it isn't heavy programs

Why OpenJ9?

OpenJ9 has extremely low RAM usage, though if you get any issues report them to OpenJ9, not the mod/plugin creator

Server

Steps

  1. Follow step 1 of client, Singleplayer
  2. Then, step 2 (if on Linux), and step 3 but instead of dragging a slider to set RAM, take the flags from step 4 and put -Xms12G -Xmx12G before them (replace 12 with the amount of RAM you can give), also, make sure to NOT give over 12GB of RAM because it will make performance worse.
    Example launch command:
LD_PRELOAD=/usr/lib/libjemalloc.so MALLOC_CONF=abort_conf:true,background_thread:true,narenas:4,dirty_decay_ms:1000,muzzy_decay_ms:1000 java -Xms12G -Xmx12G -XX:+PerfDisableSharedMem -XX:+UseStringDeduplication -jar fabric.jar

Important note

This is mainly only useful after you got mods like Lithium, Sodium (client only), C2ME (in alpha, also only useful on 8+ threads), FerriteCore, Starlight and others (I recommend going to https://modrinth.com and using the optimization filter)

FAQ

Why you should NOT use aikar's flags

They are outdated, and the G1 garbage collector finds the best options by itself, so the G1 heap options might make performance worse, however the rest of the flags is useful and I include them.

Why you should NOT use ZGC and Shenandoah IU/Default everywhere

In some cases, ShenandoahGC or ZGC can perform way worse, as shown by my tests, however they might work better in some cases

Why is the guide for Singleplayer different from Multiplayer?

Because Singleplayer has to run an internal server.

Why are these flags making my performance worse?

Because they won't work on every setup ranging from a pentium 2 to a ryzen 5950x.
Always make sure that you're able to revert changes, and make backups.

Credits

Thanks to Transformer from the CaffeineMC discord for the MALLOC_CONF env var, also thanks to ishland from RelativityMC for recommending OpenJ9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment