Updated: Feb 03, 2020 by Pradeep Gowda.
Tagged: java

JBang is a program that allows you to run .java files as scripts including downloading library dependencies using a //DEPS lib.gps:name:version syntax. It also allows you to specify JAVA_OPTIONS.

//usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA_OPTIONS -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms8m -Xmx16m -verbose:gc
//DEPS info.picocli:picocli:4.1.4
// ^^ is unused here, but shows how the import works

import static java.lang.System.*;

public class hello {
    public static void main(final String... args) {
        final var foo = 9;
        for (var i = 0; i < foo; i++) {
            out.println("Hello World");

Running the above shows the following output, which is interesting to look at the JVM/GC output: (strictly nothing to do with jbang, but I was always curious to learn more about different JVM garbage collectors, and the scripting nature of this file allowed me to experiemnt freely.)

[jbang] Building jar...
[0.008s][info][gc] Resizeable heap; starting at 8M, max: 16M, step: 128M
[0.008s][info][gc] Using TLAB allocation; max: 4096K
[0.008s][info][gc] Elastic TLABs enabled; elasticity: 1.10x
[0.008s][info][gc] Elastic TLABs decay enabled; decay time: 1000ms
[0.008s][info][gc] Using Epsilon
Hello World
... trim ...
[0.065s][info][gc] Heap: 16384K reserved, 8192K (50.00%) committed, 712K (4.35%) used

I allocated only 8M (min) memory and a max of 16M, which is sufficient to run this program. This combination of jbang and playing with GC flags may be good way to find out how much memory a “script” in Java uses and allocate that much memory instead of using system defaults. This might be beneficial in resource constrained system running java programs on a regular basis (eg: cron).

Also, if the program is a short-lived one (ie., a script), is there a need to collect garbage at the end of it? Can we just use the No-Op collector – Epsilon, which only allocates memory, but does not perform any memory reclamation.