4 ms·
Let's get straight to the really important question, can J9 or AOT help maybe just a little with clojure startup time woes?
by ledgerdev 9y ago
Let's get straight to the really important question, can J9 or AOT help maybe just a little with clojure startup time woes?
- kimi 9y agoI tried some quick tests using a fully AOT, short-running thing we run in house. Here the cost is the set-up of JVM and loading of Clojure stuff (CentOS 7 Vagrant VM on my Mac). J9: time ./jdk-9+181/bin/java -client -jar l2i-0.1.0-SNAPSHOT-standalone.jar real 0m1.987s user 0m3.383s sys 0m0.161s time ./jdk-9+181/bin/java -server -jar l2i-0.1.0-SNAPSHOT-standalone.jar real 0m2.949s user 0m5.452s sys 0m0.167s OpenJDK 8: [root@localhost ~]# time java -server -jar l2i-0.1.0-SNAPSHOT-standalone.jar real 0m1.545s user 0m2.510s sys 0m0.175s time java -client -jar l2i-0.1.0-SNAPSHOT-standalone.jar real 0m1.456s user 0m2.309s sys 0m0.182s ---- For whatever it means, this is a repeated execution of 10 runs together for J9: real 0m17.341s user 0m26.783s sys 0m1.344s And this is the same thing for openjdk version "1.8.0_144" real 0m15.169s user 0m24.573s sys 0m1.711s So I'd say that the answer to your question is is no, they are in the same class for a short-running Clojure app dominated by startup times, unless there is some special tweak.
- stewbrew 9y agoMaybe I'm missing something or I'm just blind but where is there AOT compilation in your example since you seem to run the same jar with the same command-line options. That said I'm not that surprised that class aot compilation didn't really speed up a clojure app.
- kimi 9y agoThe Clojure app was AOT compiled (Clojure->bytecode) not the JVM's AOT
- ledgerdev 9y agoThanks for checking, even if the result is not as we hoped.
- ShroudedNight 9y agoThe OpenJ9 infrastructure is somewhat different [for the better] than what I'm used to using internally, but I have only ever seen the shared class cache enabled when the -Xshareclasses [1] option is passed to the JVM. Do these numbers change significantly (especially after a warm-up run) if you add that option to J9's option set? [1] https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/com.ibm.java.lnx.80.doc/diag/appendixes/cmdline/Xshareclasses.html https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/...
- kimi 9y agosee above
- floatboth 9y agoApparently there's an option in J9 called -Xquickstart, have you tried that?
- kimi 9y agosee above
- kimi 9y agoChanges with Quickstart and Sharedclasses; # time for i in `seq 1 10`; do ./jdk-9+181/bin/java -client -Xquickstart -jar l2i-0.1.0-SNAPSHOT-standalone.jar; done real 0m18.571s user 0m30.429s sys 0m1.374s # time for i in `seq 1 10`; do ./jdk-9+181/bin/java -client -Xshareclasses -jar l2i-0.1.0-SNAPSHOT-standalone.jar; done real 0m16.642s user 0m19.483s sys 0m6.307s
- mstoodle 9y agoYou're showing the sum of all times, but do the times at least look better after the first run (with -Xshareclasses anyway) ? Depending on how smoothly your experimentation went, you may also have to destroy a pre-existing cache before you really measure it (java -Xshareclasses:destroy) as it could have stale classes in it from an earlier run. Would you be willing to open an issue with more details at http://github.com/eclipse/openj9/issues http://github.com/eclipse/openj9/issues so we can look into it?
- jacques_chester 9y agoFor OpenJDK, startup time appears to be dominated by the number of classes loaded[0]. I was told that .class files are read out of the JAR files one at a time, rather than being slurped into memory in a batch and then processed. I'd be interested in seeing whether that holds true for OpenJ9. [0] https://github.com/dsyer/spring-boot-startup-bench/tree/master/static https://github.com/dsyer/spring-boot-startup-bench/tree/mast...
- lambdadmitry 9y agoBenchmark results aside, JVM has very little to do with the startup time. Most of the time is spent wiring Clojure namespaces together: every namespace must be evaluated, every Var initialized. That takes time. The core reason for that is that namespaces and vars are dynamic, not immutable, and Clojure runtime has to evaluate everything on each startup to uphold language semantics.