As everyone here knows, I worked for months to mak...
# compose-desktop
u
As everyone here knows, I worked for months to make Nucleus handle GraalVM native compilation in a stable and production-ready way, because I own a large application in Israel with thousands of users, and I was receiving daily complaints about the app's startup time. My app integrates a search engine and uses Lucene, performing an enormous amount of computation with every search. It's true that I saw a noticeable difference in search latency—about 2x—which is why I decided to get rid of Liberica NIK and support Oracle Enterprise Edition's GraalVM native compilation with PGO. I must say that all of this is very stable today, and the performance is impressive. As I mentioned, I went from almost daily complaints to total silence (I also had many bugs related to AWT, but that's not why I'm talking today), just feature requests overall, and nothing related to the framework itself. Now, during my recent testing—keeping in mind that I test almost exclusively on Windows since it accounts for 95% of my users—I tried replacing G1 with Serial GC and saved 100 MB of RAM on a Hello World! I tried combining this with the AOT cache (Project Leyden), but on JDK 25 it simply crashes, on JDK 26 the app uses 2 GB of RAM, and on the JDK 27 EA build, without ProGuard, everything works. I get a cold boot of 1.5 seconds and total RAM usage lower than Native Image as a whole. Task Manager displays 50 MB more, but it only measures private memory, not total memory. In total, the app uses 20 MB less, and takes only 500 ms longer to start than with Native Image. I imagine this will improve even further once ProGuard supports JDK 27, not to mention that Leyden is still in its infancy. In fact, all this to say that Native Image might just be a temporary solution. @Alexander Maryanovsky If you can verify it, Serial GC seems much better suited for desktop than G1, especially if you manage to get it working normally with Leyden without RAM usage blowing up.
m
Is "-XX:+UseCompactObjectHeaders" the default now?
e
Have you thought about trying R8? I've never benchmarked a Compose Desktop app with it, but I'm hoping it would provide better optimization than Proguard.
m
This is what I found about Serial GC and I wonder if such a stop-the-world approach is really useful for a GUI desktop application. "The Serial GC is the simplest garbage collector available in the JVM (excluding Epsilon) and is designed for environments with limited CPU and memory resources. It is a stop-the-world collector, meaning that all application threads are paused during garbage collection phases."
u
@eygraber There's very little feedback on R8 for a JVM; it's mainly for Android.
@Michael Paus I use Serial GC with Native Image and I don't encounter any problems
t
Interesting findings. I’ve been using GraalVM for a long time with also great user feedback. App startup times are so much better. Using GraalVM for Windows and Linux. I’m using GraalVM Community Edition in my apps. I’ve been able to fix most AWT crashes, but I have to say fixing AWT crashes take a lot of my time. Most bugs are gone but there are still a few minor issues I can just not reproduce. I hope I can easily drop AWT from my apps in the future. I guess I will have to look into the Oracle version to try out PGO now, but the licensing looks a bit scary.
By the way, before GraalVM I used R8 with a JVM uber jar build of compose desktop. It worked great even though it is not Android!
a
@Thomas would you mind sharing any of these AWT fixes? Did you fix them at app level or a PR to the compose repo? I'm going through a similar process and any guidance on potential issues would be great
a
I hope that after my desktop ergonomics push we can retire all these workarounds and enjoy the glory of AWT 🙂
t
@Abdelilah El Aissaoui It’s mostly reflection issues, so I run an agent test to collect metadata for GraalVM. Literally everything in awt breaks unless it’s run in an agent test.
@Alexander Maryanovsky Amazing work, but unfortunately I am stuck on older compose versions for the time being. Can’t wait to update with these improvements. I’m also curious what will happen with the kotlin-desktop-toolkit library.
a
Oh, then I'm on the right path, thank you. I've been doings lots of updates to my reachability-metadata.json. So far so good at least on linux, I haven't tried yet windows (MacOS will be delayed until proper support of AWT in graalvm native-image)
I'm a bit worried of niche situations that I may be missing but I guess that's a risk worth paying
t
@Abdelilah El Aissaoui there are definitely niche situations! To name a few, input (mouse and keyboard), LocalClipboard, WindowExceptionHandler, locales, ImageIO, all Desktop.getDesktop() apis, FileDialog, different skiko.renderApi, accessibility (NVDA) crashes, javax.sound. I’m not really using reachability-metadata.json, as I just regenerate it on every release build using jvm tests. But I guess it is fine to generate it before hand.
I don’t know the situation with GraalVM on macOS, I only use GraalVM for Windows and Linux
a
As for the original comment: So far I haven't noticed any issues by using Serial GC. Once Shenandoah is added to GraalVM native image, it could be interesting for Compose desktop apps github.com/oracle/graal/issues/12237
@Thomas I've seen a few projects committing it and so far so good. There could be some situations that are complex to reproduce with tests but easy enough by hand. It's also nice in case a test breaks for some reason (even if it passes) and some parts of the metadata are missing Thank you for naming the niche situations, I'll be testing them and see if I detect any of these issues