GraalVM 22.1: Developer experience improvements, Apple Silicon builds, and more
medium.com
medium.com
The binaries are a bit large (10MB for a Kotlin hello world) but they are fast. I'll be using this for some personal cli tools since Kotlin+Maven is my personal 10x platform.
Besides cli projects I've also done some experimentation with GUI and database stuff. Using the Gluon plugin GraalVM is able to compile a native binary for a JavaFX app that talks to a Sqlite database.
When using a library that relies on reflection there might be some graalvm config to fiddle with but mostly it just works, and some of the libraries are already "native-image ready" with the necessary config inside the published package.
Back in the day, I used to use UPX on most apps, which would greatly improve launch times.
Thanks
Also, I'm using plain JavaFX with Kotlin instead of TornadoFX. Mostly because I'm not sure about the health of the TornadoFX project and I don't like some of its abstractions.
Its a shame though, for what I did understand of Truffle seemed very interesting. I do plan on trying truffle yet again in a few years, when hopefully the community size and the state of the documentation have improved.
I believe the easiest way to start a new Truffle language implementation is to fork SimpleLanguage [1] and turn it into your language. Did you try to do that?
My major blockers were -
1. Starting post ast generation was an abrupt start. An end to end tutorial - from parsing to working compiler for a tiny language like Lua, Lox, Wren etc would be very helpful. You need not deep dive into the parsing part - just give enough that we can follow along. Another option can be to continue an existing tutorial series like Lox from "crafting interpreters". That way you don't have to focus on parts which are not Truffle specific, yet users can follow along.
2. Just going through existing Java code of the Simple Language was extremely difficult for a newbie to Java, like me. I would much prefer a readable tutorial which explains all concepts in more details
3. More language examples please. As I said before, if possible do add a couple more languages like Lua. I believe Lua is already a Truffle language. Just an accompanying tutorial is missing. I remember when I tried to read through the codes of Ruby, Lua and simple language, they all started off very differently and I just got lost.
4. More tutorials. Outside of the main docs, I found only 1 comprehensive tutorial. I think it will be great if the key members make it a priority to add smalllish tutorials on things like forth, brainfuck etc in other blogs and articles.
5. Tutorials in Kotlin! I am new to the jvm, but I am digging Kotlin as a saner alternative. I think having some tuts in Kotlin would be a great help.
a. Point people to the papers to understand how the 'magic' happens.
b. Are really intended for people who already know how to build language VMs from scratch.
If you've never implemented a language interpreter at all, then you're going to struggle. Arguably not Truffle's fault, but hey, you can't drop the cost of making SOTA language runtimes by a couple orders of magnitude and then be surprised when a whole lot of newbies show up wanting to try their hand at it :)
Also I will drop my truffle seminar shamelessly here for you to watch: https://youtu.be/pksRrON5XfU
But I'm sure it's a great technology and with time the docs will get better and better.
From wikipedia [0].
What's the deal with GraalVM today? I guess Oracle is still keeping it alive since this is a post by an Oracle team.
Does it have a future or is it going to be abandoned or what is the plan?
[0] https://en.wikipedia.org/wiki/GraalVM#:~:text=The%20GraalVM%....
Most people who wanted AOT would use GraalVM directly, so for most people nothings changed. Those that did use the OpenJDK AOT will have to migrate to using GraalVM's tooling post Java 15.
Swapping out a part of a JVM as critical as the JIT compiler with a from-scratch rewrite would be a tremendously difficult and risky project even if the rewrite was done by the exact same team. Doing it when the rewrite is in a different language, all the knowledge is in a different team, in a different part of the company organizationally, in different offices and parts of the world, and also their implementation strategy to eliminate performance drops involves a completely different JVM implementation (SVM-in-HotSpot) ... well, the maintenance, budgetary and training complexities of that alone make it a tough one to digest.
I'm very hopeful they'll eventually figure out a path forward. It doesn't make much sense for Oracle to maintain three different JIT compilers (C1, C2, Graal). The biggest sticking point technically is probably the need to use native-image to produce libgraal. It'd be kinda weird for OpenJDK/HotSpot to ship two different JVMs, one that's used to implement the other. If they can find a way to AOT compile libgraal with acceptable performance, without a reliance on native-image, that'd probably be a good next step.
Graal is doing pretty well, it is heavily used by Twitter for example. And the polyglot part is simply completely novel and very exciting - it can basically optimize across language boundaries with it. A python call to a C function might get inlined and be much faster than native FFI. Enterprise edition also has managed mode for LLVM bitcode, making for example existing C code use managed heap for allocations. TruffleRuby, Graal’s ruby implementation is the fastest ruby runtime by a huge margin and the JS runtime developed by comparatively few people (compared to V8 and the like) can achieve similar performance to it.
This is interesting to me as someone working on a Rails app currently. I'm surprised it hasn't become the defacto ruby implementation given the benchmarks shown on the site. What are the drawbacks? Just Oracle ownership? Or does it require an enterprise subscription?
TruffleRuby can run Rails and is compatible with many gems, including C extensions. However, TruffleRuby is not 100% compatible with MRI 3.0 yet. Please report any compatibility issues you might find. TruffleRuby passes around 97% of ruby/spec, more than any other alternative Ruby implementation.
TruffleRuby might not be fast yet on Rails applications and large programs. Notably, large programs currently take a long time to warmup on TruffleRuby and this is something the TruffleRuby team is currently working on. Large programs often involve more performance-critical code so there is a higher chance of hitting an area of TruffleRuby which has not been optimized yet.
However, I think this is slightly outdated, because I vaguely remember a talk from one of the rubycons about Rails being slightly faster with truffle. I can't say for sure why it's not been widely picked up yet; maybe other players are looking forward to JITs within Ruby itself, or don't like the two tier model of GraalVM (you can run it for free, but it also has an enterprise version with additional performance improvements.)It is not supported on all platforms and listed as “experimental” (defined as “ features [which] are being considered for future versions of GraalVM and are not meant to be used in production”) on the platforms (Linux AMD64/ARM64, macOS [AMD64, presumably, since there is a separate listing for MacOS ARM64 where it is not supported]) that it is supported on. [0] That’s probably the main thing keeping it back from general adoption. (It’s also ~2 years behind MRI on features, but that’s less important.)
There are also notes in the TruffleRuby repo and docs that it:
(1) is possibly not fast on Rails and large programs (which are probably the bulk of where people would be looking for performance gains),
(2) has some minor incompatibilities (individually no big deal, but the aggregate could be a factor)
(3) Fibers (Ruby’s main lightweight concurrency construct) don’t have the lightweight performance they do in CRuby because they use full native threads.
[0] https://www.graalvm.org/22.1/docs/introduction/, under “Features Support”
Last I checked, Oracle's AoT compiler threw away any metadata necessary for HotSpot to be able to trace its way trough the native code, so if your AoT-compiled code was part of a hot loop, HotSpot wouldn't be able to perform any inlining or other runtime optimizations of your code. It seems like fixing this would be a first step to having a high performance JVM written in Java with start-up/warm-up time comparable to a JVM written in C++.
While we're at it, Erlang/Elixir/BEAM's NIFs seem the right way to implement native code extensions to your VM. You write implementations in your language that get replaced with native versions if the native library is successfully loaded. Maybe your non-native implementation is just a stub that throws if it's called. With a few lines at the top of your module, you can attempt to load one or more native libraries and handle/ignore any errors. This makes it much easier to gracefully degrade if a particular native library isn't available on the local machine (or even available for the platform). It's a real pain to fall back to a Java implementation if the JNI implementation isn't available for any reason.
IBM would have killed it instead, J9 already provides AOT and JIT caches, almost a decade older before such capabilities landed on OpenJDK.
Or do you mean J9?
It grew out of the Metromone project for embedded deployment.
https://researcher.watson.ibm.com/researcher/view_group.php?...
However from IBM RedBooks it looks like some of those Metronome improvements landed on J9, after Websphere Real Time product ceased to be available.
How do these Graal native-ish frameworks compare? Or more broadly, what does the scene look like today?
However, Quarkus has many distinguishing features beyond a nice dependency injection framework. First of all it is a Microprofile implementation - Microprofile is a collaborative effort among many large companies to adapt and evolve pieces of enterprise java stack to microservices. So large parts of your application would depend on Microprofile API rather than APIs specific to a particular framework like Quarkus and will be portable across Microprofile implementations (like Helidon or OpenLiberty) - for smaller individual services the benefits are minimal but it is a major advantage for larger corporations putting in decade long investments. Also, Quarkus is built atop vert.x which provides a non blocking event-loop and actor(-like) framework for JVM. Developers can choose to not bother with vert.x at all and use the MP apis exclusively but for people who like the actor-oriented programming model can choose to take advantage of it (perhaps for specific use cases). Lastly, as can be expected because it is by Redhat, there is out of the box integration with Hibernate.
Regarding the scene, Spring is also pushing into the Graal ecosystem with native features - but they are still a bit late to party. They do have a huge ecosystem to support and can't afford breaking changes so it is understandable that good spring support for Graal is an evolving multi-year effort. But it does mean that early adopters like Micronaut and Quarkus have an edge.
Also, irrespective of how well mainstream adoption for Graal pans out, I am quite happy about the growing initiative to move start-time work to build time which improves start times for non-graal deployments too.
What is the Graalvm + Clojure situation? A quick web search shows some use cases. I find the idea of using high programmer-efficient Lisp languages and then building small and fast native applications to be compelling. That said, LispWorks, SBCL, and Allegro CL are all good for building standalone apps.
https://medium.com/graalvm/improving-performance-of-graalvm-...
I didn't know this. Why is this?
Other than that, it was actually very pleasant.
- babashka (https://github.com/babashka/babashka)
- clj-kondo (https://github.com/clj-kondo/clj-kondo)
- jet (https://github.com/borkdude/jet)
SCI (https://github.com/babashka/sci) is a Clojure interpreter that allows you to evaluate Clojure code even inside of the final native binary and is used in all of the above projects.
Feel free to bug me with questions in the graalvm channel on Clojurians Slack.
I’d love to use Clojure for this, but it doesn’t seem well suited to running in a small, shared environment. Or is it now that there’s AOT?
You’ll definitely want to restrict the JVM by memory, either by explicit flags (-Xmx ) or by running them in a cgroup or container.
That said, seems like you should be able to do something pretty similar fairly easily with jars and the JVM (you may not want to run lots of JVMs in the method you're describing, since if you're calling these processes in a one-shot, CGI-style fashion, the JVMs startup time and memory requirements is going to be annoying.)
GP also linked babashka which may be closer to your interests, as its an interpreter for small scripts like these, but also comes with a mechanism (pods) for loading dependencies (like SQLite).
> An easy to use, drop-in Clojure replacement for php scripts
> Allow multiple websites to be hosted on a single $5 VPS
> The utility is a simple binary, built with GraalVM, that allows you to work effectively with pcp.
Note that not all of PCP is AOT compiled. Just the command line utility. There's a daemon as well.
BTW, I enjoyed your ClojureScript+Node.js talk a few weeks ago.
Not quite what you were asking for, but I wanted to chip in as another happy Clojure + GraalVM native user.
I'm also hoping for official support for static linking. Right now, it's an undocumented feature done through the Feature API.
That's incorrect.
TruffleRuby doesn't run complex Rails App yet. That is still a goal / target.
No TruffleRuby is still very much faster than any other Ruby JIT. YJIT does startup faster yes that's the goal.
https://eregon.me/blog/2022/01/06/benchmarking-cruby-mjit-yj...
Do you see by the end of 2022, Rails being able to run on TruffleRuby?
Lol it was. I don't know - it's research it's open ended.
Thanks for your great work!
The problem to my knowledge is that such a complex platform can even depend on some buggy side-effect down the line, so perfect interop is hard.