back
89 comments
"As such, it is supposed to require fewer CPU and memory resources, provide better startup times, and be easier and cheaper to deploy."

So we don't even know if it actually makes things faster? Startup are a none issue, CPU / memory is but you need proof for that.

Graal does not support ZGC or Shenandoah so it's hard to say if the G1 version from Graal is up to speed.

Disclaimer: I work on the GraalVM team.

The students "measured noticeable reductions in terms of memory footprint of up to 43%" [1] in some preliminary experiments. More from the accompanying blog post:

"We also hope that the Minecraft community builds on our work and helps benchmark different configurations for native Minecraft servers in more detail and in larger settings."

Please feel free to share any numbers on CPU/memory usage with us!

[1] https://medium.com/graalvm/native-minecraft-servers-with-gra...

Note that the memory usage _could_ potentially be significantly improved for the JVM by just using an alternative allocator, such as jemalloc. In our system, we saw, in some instances, native memory usage decrease by about 60%, and it also resolved a slow "leak" that we saw, since glibc was allocating memory, and not returning it to the OS. In our case it was because we were opening a lot of class loaders, and hence zip files, from different threads.
Why is this? I thought the JVM already did somewhat decent JIT compilation ...

If I understand the article correctly, you're preempting all possibly unoptimized/expensive code paths (reflection) by attempting to literally execute all of them? While it's a cool experiment, isn't it a bit error-prone (besides being a lot of effort of course, but playing Minecraft on the side does sound pretty fun!)?

Is there any benefit to simply running/JIT the client and server on GraalVM instead of JVM?
It is much worse than this because the free version of graalvm only supports the serial garbage collector. Minecraft servers and clients should be using ZGC to get rid of garbage collection pauses.
startup time is SUPER important

lets you spawn new game instances on the fly, reduce time spent loading the chunks and game data

you save a lot of money when you scale, and you improve latency, people don't complain with huge loading time and stutters for fresh servers

ask anybody working on the industry

fun fact, that's the first thing Riot did when they acquired Hytale

They rewrote their C# client to C++ for portability

And they rewrote their Java server to C++ for performance (and cost saving)

Tech Change: https://hytale.com/news/2022/7/summer-2022-development-updat...

Are they using Graal enterprise? Last I checked Community Edition of native image uses the serial collector not G1.
The students used both, the community and enterprise editions of GraalVM. Indeed, G1 is an enterprise feature: https://www.graalvm.org/22.2/reference-manual/native-image/o...
>Startup are a none issue

Yes it is. Developing any short term job -- that runs multiple seconds and goes away -- like lambda or k8s jobs with Java is meaningless for exactly this reason. The startup time is longer than the run time.

A Minecraft server is not a short term job.
The JVM can start up in less than 0.1 seconds. Depending on the amount of classes being loaded it is not an issue even for lambda and k8s jobs.
This is a Minecraft server, so it's going to be running 24/7.
I encourage my competitors to keep thinking this.
I don't think this repo provides any value. It compiles only Vanilla server, doesn't provide any benchmarks while spending whole paragraph on GraalVM Enterprise and Oracle Cloud(a single worst cloud experience I've ever had, it took me two dozen attempts to register until I finally gave up) Free Tier promotion
Shout out for Cuberite as an alternative Minecraft server project that desperately needs more volunteers

https://github.com/cuberite/cuberite

"Cuberite is a Minecraft-compatible multiplayer game server that is written in C++ and designed to be efficient with memory and CPU"

Cuberite has been demoed running on old ARM Android phones and hosting multiple players off it at once. Its performance absolutely annihilates the Java based 'vanilla' server

In a similar vein, there is also a Rust-based Minecraft server implementation:

https://github.com/feather-rs/feather

Can the same trick be used with the java client? My son runs minetest on the raspberry pi 400 as minecraft is to slow. I'll do everything for a bit more fps.
There are mods which heavily optimize the java client performance, these would have a greater effect than just ahead-of-time compilation. For instance, the modpack at https://github.com/Fabulously-Optimized/fabulously-optimized packages several of these performance mods together (see https://github.com/Fabulously-Optimized/fabulously-optimized... for the list).
Check out the sodium mod [1], if you haven't already. I've had great success eeking out a few more precious frames with it on older hardware. IIRC, it works on both x86 and ARM processors.

[1] https://github.com/CaffeineMC/sodium-fabric

> I'll do everything for a bit more fps.

Native compilation usually makes things a little slower, not faster. Using the closed-source Enterprise version, and using PGO gets it back to around the same speed as the VM version I believe currently.

Minecraft Bedrock edition runs better. It has feature parity but is not compatible with java server, and requires a new purchase IIRC.
> Minecraft Bedrock edition runs better. It has feature parity but is not compatible with java server, and requires a new purchase IIRC.

That's no longer the case. If you have one, you can "purchase" the other for free. See https://www.minecraft.net/en-us/article/java---bedrock-editi... and https://help.minecraft.net/hc/en-us/articles/6657208607501 for details.

Also, there are mods for the Java server which allow both Java and Bedrock clients to connect to the same server and play together. I don't know the details, but I have played in a server which used these mods.

This is misleading, vanilla Bedrock edition allows for a bigger render distance but has a much smaller simulation distance. There's a whole miriad of differences that they're not at all in feature parity.
Hit Shift + F3 to see a frame time breakdown, then you can determine if it is slow graphics or cpu. If it is CPU, maybe graal helps, but it's hard to tell upfront. Also check out some mods dedicated to improving performance like Sodium.
It's always CPU with Minecraft. 1 thread can't do much more.
I don't think the student looked into that at all, but I guess it depends on what the Java client uses for drawing. GraalVM Native Image currently doesn't support AWT on Linux/JDK17+, but we are working on fixing that soon.
> it depends on what the Java client uses for drawing

AFAIK, the Java client uses LWJGL, which is a native library.

I've always had some questions about graalvm so I'd like to hijack this thread, forgive the out of topic comment please!

I've got a number is spring web applications from which I create an uberjar (jar file with all dependencies) and run them in a Centos server using something like java -jar server.jar (it's a little more complex than this but you get the idea).

Would I be able to use graalvm to create native binaries from these jars? Is there some kind of tutorial describing the procedure?

Is this possible without a license/paying big money?

Finally, is this worth it? Will the apps become any faster?

Spring Boot 3 is expected to support native/graal. There is a milestone release I think.

There is a Graal Community Edition, which is free. Search for graal and spring pet clinic demo, you will likely find an article reducing startup time 100x (starting pet clinic in 15ms), and reducing memory 2-3x.

I don't know about 'faster', but in my experience most spring applications are RAM bound, not CPU bound. So the native binaries can result in scaling back to smaller and cheaper cloud instances, or smaller VMs. Imagine halving your monthly cloud instance bill, if you are looking for 'worth it'.

If you want to play with a framework where the native part works pretty okay, and still be able to use your dependent injection and dependencies, have a look at Quarkus. They even have some spring 'polyfills'.

Startup time is the major problem I have with spring, it can be ~ 1 minute in some apps. I'll definitely check Quarkus thank ypu!
I think right now this Isn’t possible with “normal” Spring because Spring and various other libraries you’ll normally use make heavy use of reflection.

Frameworks like Quarkus and Micronaut have been written with native in mind and I think Spring is also working on it (Spring Native).

Thank you for the suggestions I'll take a peek at them!
You would likely not be able to turn them to native binaries without a ton of work — spring uses reflection very heavily, so you would have to list every class that would get reflectively checked (including spring internals).

There is spring native that will solve it for the most part, but I’m not sure how hard it is to change an existing spring web app to that.

GraalVM has a community edition, which is free, I’m not sure about the license.

And it is likely not worth it, performance will likely be worth, but memory usage and startup speed will decrease. It can be worth it for command line apps or some tiny microservice that is mostly idle.

Thank you for the information! Doing some research myself I found some things about the license and integration with spring here: https://www.graalvm.org/faq/ ; it seems that no license is needed for graalvm!

I'll also take a peek on spring native it seems to be available in beta: https://github.com/spring-projects-experimental/spring-nativ...

Is Graal VM a silver bullet? Ignoring startup times, will Graal VM out perform classic JVM (IBM/Oracle etc'). I guess the optimization of the classic JVM are hard to beat. Also, cross compile is not working with Graal VM (which makes it harder to deploy than a good old Jar file).
Startup times (especially for 'on demand' cloud workloads) are kind of the point of GraalVM. Effectively, it shifts optimisation to the compile phase. GraalVM build take much more time than classic Java. But they run a bit faster (on some workloads dramatically) and use less memory. It's no silver bullet for development, if you want fast turnaround after changing your code you want the classic JVM. GraalVM can help to cut your production load a bit (although Oracle seems to keep the heavy performance gains behind for their licensed GraalVM enterprise customers)
> But they run a bit faster (on some workloads dramatically)

That’s not true. For the majority of applications the JIT compiler will be much faster (either Graal’s JIT compiler or Hotspot). Startup time, and memory reduction is true though for AOT.

I haven't noticed compile times to be any worse when using GraalVM to build Java projects.

Caveat: I also haven't been using Native Images yet, though. So I can't comment on if it'll be dramatically different for that build target.

I use GraalVM as my standard non-native JDK (OpenJDK replacement) and I'd say the performance is somewhat better.

There are a lot of non-biased benchmarks you can find online, most of them showing that Graal (both CE/EE, though particularly EE) are more performant than OpenJDK.

You then also have the option to compile to native, or to embed/run code in other languages baked in.

It's a no-lose scenario IMO.

Anecdotally I found that recent releases of OpenJDK with Hotspot were a bit faster. Both on my machine and for web services. If you don't need native images or truffle, the huge installation size isn't really justified.

There are multiple benchmarks that show marginal gains using GraalVM CE for big data workloads; it might make sense if you're still stuck on Java 8 or 11. The enterprise edition shows more significant gains.

Especially as, the last time I checked, more "modern" garbage collectors (e.g. G1) are only available in the enterprise edition.

The community version has only serial or nothing, which are ok for small heaps or short lived processes.

On some micros Graal beats C2, on some others it doesn't. It's not a silver bullet.

GraalVM is regular OpenJDK with the compiler switched out, AFAIK.

The whole advantage of GraalVM is startup time, which is important for containers, Lambda jobs etc, because it doesn't have to compile bytecode on startup. It isn't supposed to be faster than regular JVM, which has the advantage of being able to analyze and recompile hotspots.
> The native executable sometimes fails on startup. Restarting it a few times usually helps.

How would this be possible for a static native executable?

It fails for some reason when reading user data from disk. The error also goes away if you nuke the user data but that's less convenient.
No need to go for the client, it's working fine on my machine, nearly 60fps with a 12-core, 32gb + RTX2080TI with Iris, Sodium, Phosphor and Lithium </i>.
Nearly 60, lol. Also, fps are not the real problem for the client. I had a modpack with 16GB assigned crashing due to OOM errors. Forge is awesome, but modding the hell out of MC requires extreme specs.