Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Secret: Are static blocks interpreted?

DZone's Guide to

Java Secret: Are static blocks interpreted?

· Java Zone
Free Resource

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

An interesting comment was raised by @Vyadh - Are static blocks interpreted or does the JIT play a part?

When are methods optimised?

A method will be optimised when it is called often enough. This is controlled by the -XX:CompileThreshold=10000 flag. The compilation occurs in the background by default and a short time later, the optimised version of the code will be used. (Which is why it doesn't always happen at exact the 10K mark)

However, loops can also be optimised if they are called often enough. This typically takes about 2-5 seconds. This is why any bound loop which does nothing takes about 2-5 seconds. (Which is how long it takes the JIT to realise the loop doesn't do anything)

How does this apply to static blocks?

static block are never called more than once. Even if they are loaded by different class loaders, they are optimised independently. (In the unlikely event you loaded the same class 10,000 times, it still wouldn't be optimised)

However, it is quite possible to have a loop iterate many times in a static block (though rare) This can result in the static block begin optimised by the JIT.

public class Main {
    static {
        long start = System.nanoTime();
        for (int i = 0; i < 5000; i++) ;
        long time = System.nanoTime() - start;
        System.out.printf("Took %.3f ms to iterate 5 thousand times%n", time / 1e6);

        long start1 = System.nanoTime();
        for (int i = 0; i < 5000; i++) ;
        long time1 = System.nanoTime() - start1;
        System.out.printf("Took %.3f ms to iterate 5 thousand times%n", time1 / 1e6);

        long start2 = System.nanoTime();
        for (int j = 0; j < 1000 * 1000; j++)
            for (int i = 0; i < 1000 * 1000; i++) ;
        long time2 = System.nanoTime() - start2;
        System.out.printf("Took %.3f ms to iterate 1 trillion times%n", time2 / 1e6);

        long start3 = System.nanoTime();
        for (int j = 0; j < 1000 * 1000; j++)
            for (int i = 0; i < 1000 * 1000; i++) ;
        long time3 = System.nanoTime() - start3;
        System.out.printf("Took %.3f ms to iterate 1 trillion times%n", time3 / 1e6);
    }

    public static void main(String[] args) {
    }
}
run the with -XX:+PrintCompilation flag outputs.
64   1       java.lang.String::charAt (33 bytes)
     75   2       java.lang.String::hashCode (64 bytes)
Took 0.067 ms to iterate 5 thousand times
Took 0.062 ms to iterate 5 thousand times
     88   1%      Main:: @ 124 (249 bytes)
Took 4.860 ms to iterate 1 trillion times
Took 0.001 ms to iterate 1 trillion times

You can see that a loop of 5,000 is not enough to trigger optimisation, but a much larger loop does trigger optimisation. Without the JIT, there is no way the loop of one trillion time would finish in 3 seconds.

Once the method has been optimise the last one trillion loop takes practically no time at all.

Note

@Vyadh notes that the client JVM doesn't appear to perform this optimisation and will wait a very long time.

 

From http://vanillajava.blogspot.com/2011/07/java-secret-are-static-blocks.html

Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}