:graal-vm: New GraalVM release: https://www.graalvm.org/release-notes/21_0/#21002, with just bug fixes on the updater tool
Did anyone try this https://upx.github.io/ to decrease the native image size?
yes. it works, but it will inccrease startup somewhat (like it adds 100-200ms or so)
which for babashka / clj-kondo I did not find acceptable, but for clojure-lsp I can see that being acceptable since it's a long running server
I see, do you know why it increase the startup? it's kind of curious :thinking_face:
because it has to unzip stuff at startup
hum, make sense
nice, I'll give a try and try some benchmarks to see if it works nice for clojure-lsp
most people have indicated in the babashka survey 2020/11 that binary size wasn't a huge priority for them
yeah, babashka is really small, that's so cool
but clojure-lsp is with 118 mb 😞
I think what matters most is network size, so if the release file is a zip, you save network bandwidth, but on the machine the unzipped size doesn't matter much
babashka is now 70-80mb, but zipped 20mb or so
I agree, I do the same with clojure-lsp, the zip is about 30 mb
I have sometimes found that having a runtime require or resolve in your code can bloat the binary with 30 mb or so. so I usually hunt that spot down and get rid of it using alter-var-root or whatnot
build-time (top-level or macro-expansion time) require/resolve is ok though
oh, good to know! I think the only require clojure-lsp has at runtime is via dynaload
but only require nrepl if in a debug profile (not graalvm)
that dynaload could trigger the bloat still though
this is why I've made a graalvm variation of this here: https://github.com/borkdude/dynaload
you mean the borkdude.dynaload.aot
variable?
by setting the java property borkdude.dynaload.aot=true
when compiling natively, it will yield smaller binaries
I think I forgot to do that 😅 thanks!
so in the uberjar you will need to do that already
and also during graalvm compilation
Got it, will try this later, hope it'll decrease the size
to be sure, put a (println (System/getProperty "borkdude.dynaload.aot"))
at the top level in your code
yeah, I'll certainly do that hahah
Do you have an example of a project setting that variable to true @borkdude?
These properties are not part of the runtime, only during build
So you should put them on the top level and watch if they are printed during compilation
Of both Clojure and GraalVM
Oh, now it makes sense!
So, the clojure.compiler.direct-linking
was correctly configured, it was just missing the dynaload config that i"ll add now 🙂
🎉
It indeed reduced from 117MB -> 109MB 🙂
it's something indeed, with UPX this should be < 29MB
thanks for the help @borkdude
:)
just tried adding to the :jvm-opts of my :native-image profile that is used during the uberjar:
:jvm-opts ["-Xmx2g"
"-server"
"-Dclojure.compiler.direct-linking=true"
"-Dclojure.spec.skip-macros=true"
"-Dborkdude.dynaload.aot=true"]
and to the graalvm compilation flag:
"-J-Dborkdude.dynaload.aot=true"
looks the same I'm using
the println prints nil
hum, if I java -jar
it still prints nil
so the issue is the flag in the jar
so direct linking also doesn't work? good to check because that is also important
yeah, I'll check it too, probably is not working 😨
direct linking will likely make your image smaller as well
so with lein with-profile native-image run
it prints true
but with the generated jar not, let me debug
so I changed the uberjar task to this:
:uberjar {:aot :all
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
"-Dclojure.spec.skip-macros=true"
"-Dborkdude.dynaload.aot=true"]}
But even when lein uberjar && java -jar target/clojure-lsp-*-standalone.jar
I still get the nil print for all those variablesI tested a lot of params, even moving the jvm-opts to the root of the project.clj
it only work for lein run
I checked babashka and the config is the same
has anyone any experience making a native image with the Kafka client lib in it?
This seems to compile a producer and consumer with clojure: https://github.com/dainiusjocas/clojure-kafka-graalvm-native-image Maybe can help you
There is also this: https://github.com/tzzh/pod-tzzh-kafka A pod which you can use from babashka scripts.