Java for Minecraft in a nutshell

10 min read

June 8, 2025

What is Java?

Java is a high-level multi-paradigm programming language famous for its ability to compile to platform-independent bytecode. Instead of compiling to machine code like C or Rust, Java compiles to bytecode that can be executed on any platform with a Java Virtual Machine (JVM). So it’s both compiled and interpreted language at the same time.

To run a Java program, you only need to have a Java Runtime Environment (JRE) installed on your system. You don’t need JDK (Java Development Kit) to play Minecraft. JDK is only useful for developing Minecraft mods. I personally recommend using JRE instead of JDK if you don’t develop Minecraft mods because JRE is about 4 times smaller than JDK.

Java versions for Minecraft

There are 3 Java versions for Minecraft:

  • Java 8 (,1.16]: Minecraft 1.16 and older.
  • Java 17 (1.16, 1.20.5): Minecraft 1.20.5 and older.
  • Java 21 [1.20.5,): Minecraft 1.20.5 and newer.

For Minecraft version 1.6.x and older, I have not tested yet since I don’t play these versions. If Java 8 is not working on these versions, you can try other older versions like Java 7 or 6.

Furthermore, if your are playing an old modpack and it supports newer Java version, you should choose the version that supports newer Java version. For instance, GregTech New Horizons has two versions: the first one uses Java 8, and the second one uses Java 17+. You should choose the second one because newer Java versions have a better Garbage Collector.

What JRE/JDK should I use?

Differences between each distro are not that significant, at least not when it comes to gaming. You can use any JRE/JDK distro you like.

Some distro use OpenJ9 JVM which is designed for running cloud applications cost-effectively in the cloud so it is not suitable for running Minecraft client.

Should I use OpenJ9 JVM for hosting Minecraft server?

No, it is not designed for game servers.

Memory allocation

Minimum and maximum (-Xms and -Xmx) memory should be set to the same value because when minimum memory is lower than maximum memory, you have unused memory and used memory is wasted memory. Sizes must be set in Megabytes (-Xms4096M) or Gigabytes (-Xmx8G)

JVM Flags

JVM flags (or JVM arguments, etc.) are used to configure the JVM. These are a little bit complex and not friendly for beginners.

Garbage Collector (GC)

Garbage Collector (GC) is a JVM’s mechanism that identifying and reclaiming heap memory that are not longer reachable in program. It runs in the background to free up memory, reduce leaks and improve overall applications performance.

There are some GCs available in Java, including the Serial GC, Parallel GC, ZGC, Shenandoah GC, G1 GC, etc.. Each GC has its own strengths and weaknesses, and the best choice depends on the specific use case. There is no the best GC for all use cases, and you should choose the one that best fits your needs.

Throughput denotes the speed at which a Java application runs. For example, if your application is a transaction-based system, high throughput means that more transactions are executed during a given amount of time.

Pause time is the duration during which the application is temporarily frozen while the GC is running. For example, if you are playing Minecraft and the screen suddenly freezes for 0.5 seconds, it means that the GC is running.

Throughput and pause time are inversely proportional to each other. They key in here is finding the equilibrium between them.

GCThroughputPause time
Parallel GCHighLong
G1 GCSlightly highMedium
Z GCMediumVery Low
Shenandoah GCMediumLow

I personally suggest using the G1 GC or Z GC for both client and server. Shenandoah GC is not always included in every JVM distributions
To enable GC, you can use the following JVM arguments:

  • -XX:+UseG1GC: Enables the G1 GC.
  • -XX:+UseZGC: Enables the Z GC.
  • -XX:+UseShenandoahGC: Enables the Shenandoah GC.

JVM flags presets

For server, you can use Aikar’s flags. He did well in tuning JVM and explaining JVM flags.
For client, change your GC or just do not tune JVM :)