Category Archives: Uncategorized

What is private in Java 9?

When doing interviews I experience that most of the candidates do not know what private modifier in Java really means. They know something about it that is enough for every day coding, but far from complete. It is not a problem. Knowing enough is, well… enough. But it is still interesting to know some of the inner working of Java. In some rare cases it may shed light on some details. If nothing else then it is entertaining .orElse(whyDoYouReadIt) ?


By the way: mentioning interviews is a good opportunity to write rants even if the statements and implications related to my person are, in my view, false. After all, my person is not important and distancing myself from the fact that it criticizes me I find that article interesting and the conclusions about the interviews are important and actually totally in line with my opinion.

This article is to describe some of the Java facts hopefully in a bit more readable way than reading the language standard.

So what is private?

private is an access modifier in Java. If you have a private member (method, field, inner or nested class or a nested interface) of a class it can only be used by code, which is in the same class. The interesting question is: what happens when there are more than one classes that the private method is in? How can it be in more than one class? In case there is a class that contains another class and there is a private method inside the inner/nested class then it is inside the inner/nested class and also in the top level class.

Can a private method inside an enclosed class called from the outer class? Can a code inside an enclosed class call a private method in the outer class? The answer is yes in both cases. The sample code

package javax0.package1;

class TopLevelClass {

  void topMethod(){
    NestedClass nc = new NestedClass();
    nc.method();
  }
  
  private int z;

  interface NestedInterface {
    default void method(){
      TopLevelClass tlc = new TopLevelClass();
      tlc.z++;
    }
  }

  static class NestedClass {
    private int k;

    private void method() {
      TopLevelClass tlc = new TopLevelClass();
      k = tlc.z;
    }
  }
}

clearly shows this situation: the nested class NestedClass and the nested interface NestedInterface both contain code that can access the outer class contained private field z. Similarly the top level class code can call the private method inside the nested class. The fact that this sample code does not actually perform anything reasonable is not important in this case.

If we compile this single source file we get three class files:

  1. TopLevelClass$NestedClass.class
  2. TopLevelClass$NestedInterface.class
  3. TopLevelClass.class

That is because the JVM does not know what is top level and what is nested. The JVM does not know anything about nested and top level classes. For JVM a class is just a class. A top level class if you insist. That is mainly because the Java language 1.0 did not have nested and inner classes and the JVM was designed according to that. When inner and nested classes were introduced in Java 1.1 the compilation was modified only instead of the JVM so that the inner and nested classes remained a language feature but not handled by the JVM directly.

How can the top level class access a private method in another class that was nested in the source code, but when it is compiled it is just another “top level” class. They are on the same level. If the accessibility were changed to public then we could also access it from other classes, but we can not. The compiler will not allow any other code in other classes to access the private method and even if we did some trick to overcome the compiler the generated class fill will make the JVM to throw an exception. Private in Java is private.

What really happens is that the compiler generates special getter and setter methods to get access to the field z.

Such a bridge method is created for every private field or method that is accessed from a different class inside the same top level class. If the private whatever is not accessed from the enclosing class then the method is not generated. If the field is only read then only the getter is generated, if it is only set from outside then only the setter is generated.

This is also an interesting failure believing that a private field (or whatever) is accessible only from within the same object. That is the usual way we use these members when we program, but if the code has a reference of another instance of the same type then through that reference we can access the private fields of the other object just as good as we can access “our own” fields. Is this a rare case? You may think because you rarely program it. But in reality it is extremely frequent: the IDE usually generated the code for us and that is why some developer does not think about that. Without this it would hardly be possible to code the equals(Object other) method of classes.

What about Java 9?

So far there is nothing specific to Java 9 in this article and these days every Java article should be about Java 9 (or 10 already?).

If we look at access control generally then we have to talk about JPMS, and there are many great articles about that. codeFx has a good list of articles about it. Stephen Colebourne has nice articles.

Soon you will be able even to buy books about Java module systems from different publishers. I am in a lucky position that I can already read one in draft from Packt as a reviewer and I love it. But JPMS does not change “private” on this level. Still there will be nested classes and inner classes and bridge methods exactly the same way as before.

The little difference is that Java 9 now has private methods inside interfaces. This means that now we should be prepared to have syntethic bridge methods not only in inner and nested classes, but also in interfaces.

Takeaway …

Sometimes the simplest things are not as simple as they seem. After all the whole IT technology, science, engineering is nothing else but a bunch of zeroes and ones. It is just that we have a lot of them. Really a lot. If there was something new to you in this article then it should tell you that there are areas in the Java language and in the JVM that you may be interested to examine a bit more. For example:

  • What is the difference between a nested and an inner class?
  • Can you have a nested interface inside a class and similarly can you have an inner interface inside a class?
  • What about classes or interfaces inside an interface? Can you have an inner class in an interface? How about a nested class?
  • Can you write a code using reflection that list all the methods a class has? Will it list the synthetic methods? What modifiers will it have?
  • When you compile an inner class it will have the compiled name Outer$Inner.class, which is a legitimate name. But what happens if there is a Outer$Inner.java source file? Figure it out!
  • The generated synthetic methods also have legitim names. What happens if you define a method with that name? Is it Java specification or implementation specific what you see?
  • How deep can you nest inner and nested classes and/or interfaces? Can a nested class contain an inner class? Can an inner class contain a nested class?
  • What is your guess, why there is no symbolic name in the JDK for the synthetic modifier? Why can the actual modifier value be the same as the value for volatile fields?
  • Can you have a static field, class or method inside a nested class?

The answer to those questions and the knowledge is not practical, I know. I have never ever seen any code or project where knowing that an inner class can not have a static field was giving any advantage. On the other hand thinking about these, getting the answers may give you some joy, like solving crosswords if that is your taste and a knowledge that still may be useful aiding to the understanding the technology in a way that we do not recognize. In some situation one person just finds a bug faster than other because she “feels” the technology. That is when you can not tell what was whispering the solution to your ears but something, knowledge like the above did. But it will only if you love to dig into those fine bits of the technology.

Last a trick question, even less practical than those above just for entertainment, if you like:

Puzzle

We know that it is not possible to have a static field inside an inner (not nested) class. Is it still possible to have a compiled class file generated by the Java compiler from an inner class that has a static method?

Process Handling in Java 9

Managing operating system processes in Java was a daunting task all times. The reason for that is the poor tooling and poor API that are available. To be honest that is not without reason: Java was not meant for the purpose. If you wanted to manage OS processes, you had the shell, perl script whatever you wanted. For larger applications that faced tasks that are more complex, you were supposed to program the issue in C or C++.

When you really had to manage processes from Java you had to create operating system dependent code. It was possible, you could query some environment variables and then you could implement different behavior depending on the operating system. This approach works until Java 8 but it has several drawbacks. Testing costs more, development is more complex. As Java became more and more nature and widespread the demand for this type of applications arose. We can clearly see for example that the question https://stackoverflow.com/questions/6356340/killing-a-process-using-java put up on StackOverflow in 2011 had more than hundred thousand of views. Some application and thus some developers need a solution for this problem, which is really a solution and not a workaround.

In this case providing an API in the JDK is a solution. It will not make process-handling OS independent. The operating systems differ and process handling is an area very much tied to the OS. The system dependent part of the code is however, moves to the JDK run time and Java development team tests it and not the applications separately. It eases the burden of testing on their side. In addition, the development becomes cheaper as the API is already there and we do not need to program it separately for BSD, OSX, Linux and Windows not to mention OpenVMS. Finally, the application may run faster. Again an example. If we needed the list of the running processes then we had to start an external process that dumps the list of the processes to the standard output. The output of this process had to be captured and analyzed as string. Now, with the advent of Java 9 we will have a simple call for that, which is implemented invoking the appropriate operating system call and it does not need the execution of a separate process, nor the parsing of a string output for an information that was already there just not available in Java.
To read about all the details of process handling of Java 9 you can read the documentation currently available on the URL http://download.java.net/java/jdk9/docs/api/overview-summary.html or you can soon read the book Mastering Java 9 from Packt https://www.packtpub.com/application-development/mastering-java-9 in which I wrote the chapter about process handling. In this article I will talk about some issues why we need the new class ProcessHandle It may not be that evident for some developers who are not that much experienced with operating system processes and how the operating system works.

ProcessHandle

In short an instance of ProcessHandle represents an operating system process. All operating systems identify alive processes using PIDs which is a TLA abbreviating Process Identifier. These are small (or not that small) integer numbers. Some operating system could use something else, like names, or some cryptic strings but they do not. There is no benefit and it happens that all of them use numbers to identify processes.

When we program in OO manner we abstract the problem so that it better explains the problem we model. There is a rule however, that we should not make our model more abstract than the problem itself. That just introduces unnecessary complexity to the application increasing cost. In this case it seems to be obvious (or rather oblivious) to use int to identify a process. If the operating system does not do it more abstract then why should we? Just because in Java everything is an object? (Btw: not true.)

The reason for that is there is no one to one match between PIDs and ProcessHandle instances. Let’s re-read the first two sentences of this section:

“… ProcessHandle represents an operating system process. All operating systems identify alive processes using PIDs …”

There is that little word “alive” in the second sentence and believe me that makes a difference. Being alive is very different from being dead, although we do not have firsthand direct comparison. A ProcessHandle instance may keep a reference to a process that is already wiped off from memory. Imagine the situation that you look at the list of the processes on Linux issuing the ‘ps –ef’ command and then you see that Tomcat is eating the CPU and consumes ever increasing memory most likely because the application you deployed has a bug looping. You decide to kill the process so you look at the pid displayed and issue the command ‘kill -9 666’ if the pid happens to be 666. By that time, the process has eaten up all the memory it could have from the OS and because you did not configure any swap file on the machine, the JVM disappears without trace. The kill process will complain that there is no process for the defined pid. It may also happen that the operating system has already started a totally different process that happen to have that pid. Has it ever happened? Now you shake your head and that is, because it has never happened in your practice. On Linux by default he maximum number that can be a pid is 32768. When will that ever wrap around? Actually not a long time, but usually not so far so that the pid is reused between issuing the ‘ps’ and ‘kill’ commands. And what happens if a small embedded system sets the /proc/sys/kernel/pid_max smaller. Say much smaller, like 16 that fits to four bits? It may not be a big problem when you issue the command interactively because you are there and if the system crashes you can restarts the process or the whole system if needed. You can do the corrective action if you made a “mistake”. Java application are not that intelligent and we should not have the chance even in an embedded system to kill a process we did not want to.

process handling based on pid

To handle that situation Java has the interface ProcessHandle. Instead of pids we have ProcessHandles. If we need the ProcessHandle of the currently running process (the JVM) then we can call the static method ProcessHandle::current (note that I used the nice Java 8 method handle notation). You can get the pid of the current process calling getPid() on that instance of ProcessHandle but after a while you will not do it. It is just an old habit wanting the pid of a process. You do not need it, when you have the handle.

When you have a process handle, say processHandle you can get a Stream calling processHandle.children(). This will list the immediate offspring processes. If you want a “transitive closure”, so you want to list not only the children but also the children of children and so on you have to call processHandle.descendants(). But what if you are really greedy and want to get a hand(le) on all processes. Then you should call the static method ProcessHandle::allProcesses.
Streams are famous for being populated lazy creating the next element only when needed. In case of process list it would lead to interesting results, therefore in this case the dataset backing the stream of processes is a snapshot created when one of the children(), descendants() or allProcesses() was called.
Now we have a handle to a process. What can we do with it?

We can processHandle.destroy() it and we can also call processHandle.destroyForcibly(). That is what everybody was wanting, as per the cited stack overflow article. We can also check if the process the handle is assigned to is still alive calling processHandle.isAlive(). You can also get access to the parent process handle calling processHandle.parent(). Note that not all processes have parent process. One of them never had and any other process may be orphan when the parent process has terminated. For this reason, the return value of this method is Optional. Java 9 has new features in the Optional class we well, but that is a different story, here we focus on the processes.

If the process is still alive but we want to wait for the termination of the process, we can do it in a modern, asynchronous way. We can get a CompletableFuture from the process handle calling processHandle.onExit() that will complete when the process terminates. Java 9 has new features in the CompletableFuture class as well, but that is a different story, here we focus on the processes. Do I repeat myself?

There is an interface inside the interface ProcessHandle called Info. We can get an instance of the information from the process handle calling processHandle.info(). Through this instance we can get access to the arguments as an optional string array, to the command line as an optional string, to the command as a string and to the user the process belongs to also as an optional string. We can also get information about when the process was started and also about the total CPU usage in form of optional Instant and optional Duration. These new classes were introduced in Java 8 and Java 9 has new features … Okay it starts to be boring.

Summary

What can we do with all these features? In the book I mention I created a simple process controlling application. A similar one I had to create around 2006 in perl. It starts processes as described in a configuration file and if any of them fails it restarts. But this is only one example. There are other scenarios where process handling can be handy. You want to fill in forms and convert them to PDF. To do that you start some word processor with command line parameters to do that. The tasks are queueing and they are started one after the other to keep reasonable performance you convert at most a configurable n document in n processes. If a process takes too long you kill it, send a message about it to the person who started the request to your conversion server and schedule it to run during the night or some less busy period.

We can develop such programs in Java without using external shell, python or perl scripts, and it simply makes the project simpler and cheaper.

Who needs Java modules after all ?

Oleg Selajev asked on twitter


Jigsaw questions for 1000. I as an X want JPMS modules. What is X if it’s not a platform developer?

My answer is that X is a human being (minus platform developers, because that was a condition). We all need module system to have safer code resulting in more reliable systems resulting in better performance in the business resulting in better economy resulting in human happiness. Perhaps I went a bit too far with the conclusions but the point is that module system is needed by everyone in the industry whether they’re aware of it or not. You will get it. First of all we should start with the ob(li)vious answer to the question.

Nicolai Parlog said: Every library developer whose types are not all public.

Very true. As a library developer I want to design my libraries so that I separate the API. I wan to separate the public interface from the implementation. This is what we, programmers call “encapsulation”. This is soooo good to encapsulate. We love to do it! We do it, because it is hilarious! We love it!

On the second thought though we do it because it is a tool to create reliable bug free (he he he) software.

It helps the code developers who use my code that encapsulates the internal state and implementation to write better code. It is a bit like raising children. I as parent disallow certain things that they would do. Eat lots of chocolate, stay up late and so on. And this is for their own good, even though they do not see or understand it at the moment. Later, of course, when they grow up and become parents themselves they will understand and do the same. It is not much different with library developers and library using programmers, except, perhaps, that programmers never grow up.

Similarly I as a library developer need JPMS for the sake of the developers who are going to use my code. My library will not be better or worse just because I encapsulate. (Side note: it will be better, but not because of the lessened number of bugs in it.) I can easily get the implication that I as a library developer want JPMS the least. Who cares if you, dear programmer, shoot off your testicles using my library? It is your responsibility to call only the public API and not some frequently modified internal class and method. Or is it?

Not really. It is also my responsibility to create a library that is easy to use and hard to make mistakes using it. This is what we call usability. This is where JPMS module system comes into the picture. Without JPMS I can document what packages are public and which are implementation specific. The contract between me and the users of the library is that they will not use the privates of my library and for this well behaviour I will keep the public part of the library stable so that they do not need to change their code from release to release. (Btw. has anyone ever realized how literally bloody this name, jPMS is? What the fly? PMS, really? Not to mention seeing currently all the cramps related to it: nomen est omen. It was not a lucky baptism.)

Let’s get back on our rail: why do we need module system for that? Developers are disciplined (he he he) people and they do not want to harm themselves. They should not and they will not use internal code of the library. That is not good for them on the long run and they are well aware of that. The catch is the long run thingy. In the long run we are all dead. There will be a point during the development, typically a few days before release date, when some of the internal APIs of a library just seem lucrative to be used. In some weird way those internal calls are just exactly what you need. You know that you are not supposed to use them, and there is a good, well-mannered solution, but that needs more time to develop. It is just that with the release date approaching you do not have the time to follow that pattern. Not to mention feeling proud about the “I can do that”, “how well I know these tools” thoughts, instead of feeling shame tampering with the parts of the library that are private.

That is where Java Module System comes into the picture. You will not be able to do shortcuts. You will sigh remembering the good old days when Java was open to the whole world whatever there was on the classloader (not to mention FORTRAN programming, am I right or just the contrary I am right?) but you will follow the rules, because it just will not work otherwise.

You think that you are not vulnerable to such vanity as using the internal parts of a library. Here is a test: did you recognize that I used the expression “internal APIs of a library”? If not, then feel ashamed but don’t admit it. No need. Java Module System will help to forget things that do not exist, like internal API. Nonsense. API is public. There is no such thing as internal API. The resulting code will be better, easier to maintain, less prone to library upgrades and thus cheaper at the bottom line.

In the long run, when we are all dead our offspring will create better code and having module level encapsulation will be an obvious thing, just like world peace will be that time.

So I need Java Module System, you need it, and everybody else needs it for a better world and for the sake of world peace.

Disclaimer: The author of the article no speaks English as naive language 😉

How object initialization works

You may got used to my habit writing about something special, non trivial Java feature or usage. This time it will be a little different. At least for the start. This is a video tutorial about object initialization. We have an interface. Then we have an abstract class that implements the interface and then a concrete class that extends the abstract class. They do nothing except writing some strings to the console when they are executed so we can see what order they are executed. They have static initializer blocks, wherever it possible, non static initializer blocks and constructors.

BTW: can you tell, and be honest to yourself: is it allowed to have a static initializer block inside an interface? If you know java very well, but you can not answer that question with absolute certainty it will not hurt to watch this 9 minute tutorial.

And also stay tuned for the second part, when we get back to real javax0 style and let the hell loose.

While you wait for the second tutorial here is a puzzle:

How is it possible to have an instance of the Concrete class even though calling new Concrete() throws
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class com.javax0.classinit.Concrete

If you could or could not find the answer to the puzzle watch the second part of the tutorial:

The source code is available from https://github.com/javax0-tutorials/object-initialization.

Java 9 by Example, My New Book

Sometime during the summer, I decided to write a book on Java programming after being suggested to do so by Packt. Java is a market leader and the number one programming language in the enterprise programming arena, and learning it is a good option for novice programmers. I recommend it to be learned as a main language after you got your fingers burnt with languages that have a simpler ecosystem, such as Python, Delphy, VisualBasic, and so on. Many advocate the death of Java but I do not share their opinion. There may be more modern and fancier languages, but for enterprise computing Java is still there and will be there, at least for the next 20 years. If you learn Java now, you learn an actively developing, stable, and reliable environment and tool, and you gain significant knowledge that you can convert to “jobs” in the coming decades.

An overview of the book

While designing the book, I decided to address those readers who already have some programming experience and want to learn Java as a main language, but apart from that, the book starts with the basics. Java 9 is especially good to get started since it has a REPL interpreter that compiles the Java code you type in, so you can try the features interactively. Throughout the book, you will see sample programs, first simple ones and then more complex examples, that are explained in detail. We focus not only on the language features, such as module support, functional programming, lambda expressions, and reactive interfaces, but also on programming style and program design. Continuously tutoring and coaching junior developers in my everyday work, I have gathered some experience on what is important and yet easily overlooked by beginners, and I have focused on these issues in the book.

The examples include sorting algorithms, explaining bubble and quick short, a game called Mastermind, a sample e-Commerce application, and a simple accounting application. The game, Mastermind, is followed in three chapters: the basic algorithm, a massively parallel algorithm (which is not trivial for this problem), and a web application where you can finally see the colors on the screen.

Finishing the book, the reader will have a comprehensive view of the language and will gain a stable basic knowledge to study further in the special directions he or she chooses.

Java 9 by Example Book Cover

How to get the book

This book is currently work in progress at the moment. You can however get an early access eBook from the Packt Website at https://www.packtpub.com/application-development/java-9-programming-example. Here you can see pre-reviewed drafts of the chapters as they are written, giving you access to content as early as possible. To know more about Early Access click on the below link. https://www.packtpub.com/books/info/packt/early-access

Final volatile

I was writing my book over the weekend and I was looking for some simple example that could demonstrate the real need of volatile modifier in multi-thread code. Years ago when I last time demonstrated the multi-thread capability Java was still 32-bit, or at least there was 32-bit Java available. On 32 bits you could concurrently increment long variables and because the lower and upper 32 bits were handled in different processor shift there was a chance that two threads garbled some way the non-volatile variable. Now with Java 9 this is not the case. Now Java is 64-bit and I had to demonstrate the need for a volatile on 64-bit before anyone comes up the stupid idea that it was only needed for 32-bit. (I could tell stories, but I try to keep it a professional blog. Not with much success, but still.)

I was searching stackoverflow and found this page that contains many meaningless, or less than usable answer (which clearly demonstrates that the topic is not simple) but it also contains a sample from Jed Wesley-Smith that inspired my demonstrating code for the book:

package packt.java9.by.example.thread;

public class VolatileDemonstration implements Runnable {
    private Object o = null;
    private static final Object NON_NULL = new Object();
    @Override
    public void run() {
        while( o == null );
        System.out.println("o is not null");
    }
    public static void main(String[] args)
                           throws InterruptedException {
        VolatileDemonstration me = new VolatileDemonstration();
        new Thread(me).start();
        Thread.sleep(1000);
        me.o = NON_NULL;
    }
}

This code will never finish, unless you convert the field o volatile. We also need the 1000ms sleep to allow the JIT to optimize the code of the method run() after which it never reads the variable o ever again. The JIT assumes intra-thread semantics and takes the liberty to optimize the code that way. (Java Language Specification 17.4.7)

But what happens if you have a field that you can not convert to volatile? What? Can’t you just write the keyword volatile in front of the type Object? Perhaps I was giving too much hint in the title of the article…

A final field can not be volatile. Of course: a final can not change, there is no point to re-read it from the main memory and waste CPU cycles for the synchronization of any change of it between the CPU caches. But that is not true.

Final variables can be changed once.

This is something that novice Java developers tend to forget. When an object is created any final field has the zero value. In case of an object this value is null. The field has to get its final value until the end of the initialization process, that is until the end of the execution of the constructor (any constructor). Look at the following code:

package packt.java9.by.example.thread;

public class VolatileDemonstration implements Runnable {
    private final Object o;
    private static final Object NON_NULL = new Object();
    @Override
    public void run() {
        while( o == null );
        System.out.println("o is not null");
    }

    public VolatileDemonstration() throws InterruptedException {
        new Thread(this).start();
        Thread.sleep(1000);
        this.o = NON_NULL;
    }
}

The constructor starts the new thread, sleeps and then sets the field that can not be volatile. What is the solution?

What solution? There is no solution! This is a demonstration code. Just don’t write code that does things like this: that is the solution. OK?

Takeaway

What can we learn from this? Not all of the followings can be directly implied from the above, but they are all related to the phenomenon. I could write a longer article leading to any of the followings but it would have only abused your patience.

Juniors

  • Final fields can be changed once. It is not true that they are not changing never (sic).
  • A thread may read the value of a final field once and it may not read it ever again. If the JVM runs for years the thread may keep the value in the thread context in some registry or CPU cache for years as long as it likes.
  • Never let this escape from the constructor.
  • Among other more trivial things the “never let this escape from the constructor” also means not to pass it as argument to a method that can be overridden or not under the control of the programmer, who is responsible for the current class.
  • Write well behaving code or else you will suffer the slings and arrows of your outrageous program.

Seniors

  • See the takeaways for juniors and teach them.
  • You have a nice brain twister code for education.
  • Java is not a perfect language allowing such constructs. But do not tell juniors. When they realize it they are already seniors and then it is just too late.
  • The solution is a liquid mixture in which the minor component is uniformly distributed within the major component.

Microbenchmarking comes to Java 9

I have not written article here for a few months and this will also continue with this exception. I plan to return writing around next year March. Explanation at the end of the this article. Wait! Not exactly at the end, because you could just scroll down. It is somewhere towards the end of the article. Just read on!

Three years ago I was writing about how Java compiler optimizes the code it executes. Or rather how javac does not do that and the same time JIT does. I made some benchmarks, some really bad ones as it was mentioned by Esko Luontola. These benchmarks were meant to show that JIT optimize even before it could gather significant statistical data about the execution of the code.

The article was created in January 2013. and the very first source code upload of JMH (Java Microbenchmark Harness) happened two month later. Since that time the harness developed a lot and next year it becomes part of the next release of Java. I have a contract to write a book about Java 9, and its chapter 5 should cover Java 9 microbenchmarking possibilities, among other things. It is a good reason to start something to play with around JMH.

Before getting into the details how to use JMH and what it is good for, let’s talk about a bit microbenchmarking.

Microbenchmarking

Microbenchmarking is measuring the performance of some small code fragment. It is rarely used and before starting to do a microbenchmark for real commercial environment we have to think twice. Remember that premature optimization is root of all evil. Some developers created a generalization of this statement saying that optimization itself is root of all evil, which may be true. Especially if we mean microbenchmarking.

Microbenchmarking is a luring tool to optimize something small without knowing if it is worth optimizing that code. When we have a huge application that has several modules, run on several servers how can we be sure that improving some special part of the application drastically improves the performance? Will it pay back in increased revenue that generates so much profit that will cover the cost we burnt into the performance testing and development? I am reluctant to say that you can not know that but only because such a statement would be too broad. Stadistically almost sure that such an optimization including microbenchmarking will not pain off most of the time. It will hurt, you just may not notice it, or even enjoy it, but that is a totally different story.

When to use microbenchmarking? I can see three areas:

  1. You write an article about microbenchmarking.
  2. You identified the code segment that eats most of the resources in your application and the improvement can be tested by microbenchmarks.
  3. You can not identify the code segment that will eat most of the resources in an application but you suspect it.

The first area is a joke. Or not: you can play around with microbenchmarking to understand how it works and then to understand how Java code works, what runs fast and what does not. Last year Takipi posted an article where they tried to measure the speed of lambdas. Read it, very good article and clearly demonstrates the major advantage of blogging over writing something for the print. Readers commented and pointed out errors and they were corrected in the article.

The second is the usual case. Okay, before a reader, commented corrects me: the second should have been the usual case. The third is when you develop a library and you just do not know all the applications that will use it. In that case you will try to optimize the part that you think is the most crucial for most of the imagined, suspected applications. Even in that case it is better to take some sample applications.

Pitfalls

What are the pitfalls of Microbenchmarking? Benchmarking is done as experiment. The first programs I wrote were TI calculator code and I could just count the number of steps the program made to factor two large (10 digits that time) prime numbers. Even that time I was using an old Russian stop watch to measure the time being lazy to calculate the number of steps. Experiment and measurement was easier.

Today you could not calculate the number of steps the CPU makes. There are so many small factors that may change the performance of the application that are out of control of the programmer that it is impossible to make a calculation of the steps. We have the measurement left for us and we gain all the problems with all the measurements.

What is the biggest problem of measurements? We are interested in something, say X and we usually can not measure that. So we measure instead Y and hope that the value of Y and X are coupled together. We want to measure the length of the room, but instead we measure the time it takes for the laser beam to travel from one end to the other. In this case the length X and the time Y are strongly coupled. Many times X and Y only correlate more or less. Most of the times when people do measurement the values X and Y have no relation to each other at all. Still people put their money and more on decisions backed by such measurements. Think about the political elections as an example.

Microbenchmarking is no different. It is hardly ever done well. If you are interested in details and possible pitfalls Aleksey Shipilev has a good one hour video. The first question is how to measure the execution time. Small code runs short times and System.currentTimeMillis() may just return the same value when the measurement starts and when it ends, because we are still in the same millisecond. Even if the execution is 10ms the error of the measurement is still at least 10% purely because of the quantization of the time as we measure. Luckily there is System.nanoTime(). We happy, Vincent?

Not really. nanoTime() returns the current value of the running Java Virtual Machine’s high-resolution time source, in nanoseconds as the documentation says. What is “current”? When the invocation was made? Or when it was returned? Or sometime between? Select the one you want and you may still fail. That current value could have been the same during the last 1000ns that is all Java implementations should guarantee.

And another caveat before using nanoTime() from the documentation: Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not correctly compute elapsed time due to numerical overflow.

292 years? Really?

There are other problems as well. When you start up a Java code the first few thousand executions of the code will be interpreted or executed without run-time optimization. JIT has the advantage over compilers of statically compiled languages like Swift, C, C++ or Golang that it can gather run-time information from the execution of the code and when it sees that the compilation it performed last time could have been better based on recent run-time statistics it compiles the code again. The same may be true for the garbage collection that also tries to use statistics to tune its operational parameters. Because of this well written server applications gain a bit of performance over time. They start up a bit slower and then they just become faster. If you restart the server the whole iteration starts again.

If you do micro benchmarks you should care about this behavior. Do you want to measure the performance of the application during warm-up time or how it really executes during operation?

The solution is a micro benchmarking harness that tries to consider all these caveats. The one that gets to Java 9 is JMH.

What is JMH?

“JMH is a Java harness for building, running, and analyzing nano/micro/milli/macro benchmarks written in Java and other languages targeting the JVM.” (quote from the official site of JMH)

You can run jmh as a separate project independent from the actual project you measure or you can just store the measurement code in a separate directory. The harness will compile against the production class files and will execute the benchmark. The easiest way, as I see, is to use the Gradle plugin to execute JMH. You store the benchmark code in a directory called jmh (the same level as main and test) and create a main that can start the benchmark.

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.io.IOException;

public class MicroBenchmark {

public static void main(String... args) throws IOException, RunnerException {
Options opt = new OptionsBuilder()
.include(MicroBenchmark.class.getSimpleName())
.forks(1)
.build();

new Runner(opt).run();
}

There is a nice builder interface for the configuration and a Runner class that can execute the benchmarks.

Playing a bit

In the book Java 9 Programming By Example one of the examples is the Mastermind game. Chapter 5 is all about solving the game parallel to speed up the guessing. (If you do not know the game, please read it on Wikipedia, I do not want to explain it here, but you will need it to understand the following.)

The normal guessing is simple. There is a secret hidden. The secret is four pegs of four different color out of 6 colors. When we guess we take the possible color variations one after the other and ask the question the table: if this selection is the secret are all answers correct? In other words: can this guess be hidden or is there some contradiction in the answers for some previous answers? If this guess can be the secret then we will give it a try putting the pegs on the table. The answer may be 4/0 (alleluia) or something else. In the latter case we go on searching. This way the 6 color, 4 columns table can be solved in five steps.

For the sake of simplicity and visualization we name the colors with numbers, like 01234456789 (we have ten colors in the jmh benchmark since 6 colors are just no enough) and 6 pegs. The secret we use is 987654 because this is the last guess as we go from 123456, 123457 and so on.

When I first coded this game in August 1983 on a Swedish school computer (ABC80) in BASIC language each guessing took 20 to 30 seconds on the z80 processor running on 40MHz 6 colors, 4 positions. Today my MacBook Pro can play the whole game using single thread approximately 7 times in a second using 10 colors and 6 pegs. But that is not enough when I have 4 processors in the machine supporting 8 parallel threads.

To speed up the execution I split up the guess space into equal intervals and I started separate guessers each spitting guesses into a blocking queue. The main thread reads from the queue and puts the guesses on the table as they come. There are some post processing that may be needed in case some of the threads create a guess that becomes outdated by the time the main thread tries to use it as a guess but still we expect huge speed up.

Does it really speed up the guessing? That is JMH here for.

To run the benchmark we need some code that actually executes the game

@State(Scope.Benchmark)
public static class ThreadsAndQueueSizes {
@Param(value = {"1", "4", "8", "16", "32"})
String nrThreads;
@Param(value = { "1", "10", "100", "1000000"})
String queueSize;

}

@Benchmark
@Fork(1)
public void playParallel(ThreadsAndQueueSizes t3qs) throws InterruptedException {
int nrThreads = Integer.valueOf(t3qs.nrThreads);
int queueSize = Integer.valueOf(t3qs.queueSize);
new ParallelGamePlayer(nrThreads, queueSize).play();
}

@Benchmark
@Fork(1)
public void playSimple(){
new SimpleGamePlayer().play();
}

The JMH framework will execute the code several time measuring the time to run with several parameters. The method playParallel will be executed to run the algorithm for 1, 4, 5, 10 and 32 threads each with 1, 10, 100 and one million maximum queue length. When the queue is full the individual guessers stop with their guessing until the main thread pulls at least one guess off the queue.

I suspected if we have many threads and we do not limit the length of the queue then the worker threads will fill the queue with initial guesses that are just based on an empty table and thus does not deliver much value. What do we see after almost 15 minutes of execution?

Benchmark                    (nrThreads)  (queueSize)   Mode  Cnt   Score   Error  Units
MicroBenchmark.playParallel            1            1  thrpt   20   6.871 ± 0.720  ops/s
MicroBenchmark.playParallel            1           10  thrpt   20   7.481 ± 0.463  ops/s
MicroBenchmark.playParallel            1          100  thrpt   20   7.491 ± 0.577  ops/s
MicroBenchmark.playParallel            1      1000000  thrpt   20   7.667 ± 0.110  ops/s
MicroBenchmark.playParallel            4            1  thrpt   20  13.786 ± 0.260  ops/s
MicroBenchmark.playParallel            4           10  thrpt   20  13.407 ± 0.517  ops/s
MicroBenchmark.playParallel            4          100  thrpt   20  13.251 ± 0.296  ops/s
MicroBenchmark.playParallel            4      1000000  thrpt   20  11.829 ± 0.232  ops/s
MicroBenchmark.playParallel            8            1  thrpt   20  14.030 ± 0.252  ops/s
MicroBenchmark.playParallel            8           10  thrpt   20  13.565 ± 0.345  ops/s
MicroBenchmark.playParallel            8          100  thrpt   20  12.944 ± 0.265  ops/s
MicroBenchmark.playParallel            8      1000000  thrpt   20  10.870 ± 0.388  ops/s
MicroBenchmark.playParallel           16            1  thrpt   20  16.698 ± 0.364  ops/s
MicroBenchmark.playParallel           16           10  thrpt   20  16.726 ± 0.288  ops/s
MicroBenchmark.playParallel           16          100  thrpt   20  16.662 ± 0.202  ops/s
MicroBenchmark.playParallel           16      1000000  thrpt   20  10.139 ± 0.783  ops/s
MicroBenchmark.playParallel           32            1  thrpt   20  16.109 ± 0.472  ops/s
MicroBenchmark.playParallel           32           10  thrpt   20  16.598 ± 0.415  ops/s
MicroBenchmark.playParallel           32          100  thrpt   20  15.883 ± 0.454  ops/s
MicroBenchmark.playParallel           32      1000000  thrpt   20   6.103 ± 0.867  ops/s
MicroBenchmark.playSimple            N/A          N/A  thrpt   20   6.354 ± 0.200  ops/s

(In score the more is the better.) It shows that the best performance we get if we start 16 threads and if we somewhat limit the length of the queue. Running the parallel algorithm on one thread (a mater and a worker) is somewhat slower than the single thread implementation. This seems to be okay: we have the overhead of starting a new thread and communication between the threads. The maximum performance we have is around 16 threads. Since we can have 8 cores in this machine we expected the peek around 8. Why is that?

What happens if we replace the standard secret 987654 (which is boring after a while even for a CPU) with something random?

Benchmark                    (nrThreads)  (queueSize)   Mode  Cnt   Score   Error  Units
MicroBenchmark.playParallel            1            1  thrpt   20  12.141 ± 1.385  ops/s
MicroBenchmark.playParallel            1           10  thrpt   20  12.522 ± 1.496  ops/s
MicroBenchmark.playParallel            1          100  thrpt   20  12.516 ± 1.712  ops/s
MicroBenchmark.playParallel            1      1000000  thrpt   20  11.930 ± 1.188  ops/s
MicroBenchmark.playParallel            4            1  thrpt   20  19.412 ± 0.877  ops/s
MicroBenchmark.playParallel            4           10  thrpt   20  17.989 ± 1.248  ops/s
MicroBenchmark.playParallel            4          100  thrpt   20  16.826 ± 1.703  ops/s
MicroBenchmark.playParallel            4      1000000  thrpt   20  15.814 ± 0.697  ops/s
MicroBenchmark.playParallel            8            1  thrpt   20  19.733 ± 0.687  ops/s
MicroBenchmark.playParallel            8           10  thrpt   20  19.356 ± 1.004  ops/s
MicroBenchmark.playParallel            8          100  thrpt   20  19.571 ± 0.542  ops/s
MicroBenchmark.playParallel            8      1000000  thrpt   20  12.640 ± 0.694  ops/s
MicroBenchmark.playParallel           16            1  thrpt   20  16.527 ± 0.372  ops/s
MicroBenchmark.playParallel           16           10  thrpt   20  19.021 ± 0.475  ops/s
MicroBenchmark.playParallel           16          100  thrpt   20  18.465 ± 0.504  ops/s
MicroBenchmark.playParallel           16      1000000  thrpt   20  10.220 ± 1.043  ops/s
MicroBenchmark.playParallel           32            1  thrpt   20  17.816 ± 0.468  ops/s
MicroBenchmark.playParallel           32           10  thrpt   20  17.555 ± 0.465  ops/s
MicroBenchmark.playParallel           32          100  thrpt   20  17.236 ± 0.605  ops/s
MicroBenchmark.playParallel           32      1000000  thrpt   20   6.861 ± 1.017  ops/s

The performance increases since we do not need to go though all the possible variations. In case of one thread the increase is double. In case of multiple threads the gain is not that much. And note that this does not speed the code itself up, only measures more realistically using statistical, random secrets. What we can also see that the gain of 16 threads over 8 threads is not significant any more. This is significant only when we select a secret that is towards the end of the variations. Why? From what you have seen here and from the source code available in GitHub you can give an answer to that.

Summary

The book Java 9 Programming By Example is planned to be released February 2017. But since we are living in an open source world you can get access controlled by the publisher to 1.x.x-SNAPSHOT versions. Now I told you the preliminary GitHub URL that I use while I develop code for the book and you can also preorder the eBook and give feedback helping me to create a better book.