My application development company just got a new website. It shows more relevant information and has a lean design powered by Bootstrap. It is now hosted on Amazon EC2. If you need a software for your business, call us. We will discuss your project and we’ll give you a free quote, see our pricing and application hosting packages. All the applications we develop run on desktop, tablet and smartphone out of the box.
Alright, enough bragging, back to work now!
One great feature of VisualVM is that it can read heap dump files. Heap dumps are useful to diagnose memory leaks. See this post for more details about memory leaks and how to solve them.
Why VisualVM is slow with heap dump
Another great feature of VisualVM is that you can read a huge heap dump file and VisualVm will consume a minimal amount of memory to do so. For instance, you will be able to read a 8 Gigabytes heap dump file with VisualVM running on a development workstation having only 2 Gigabytes of RAM. In order to achieve that, VisualVM will parse the heap dump file and will create a work file on disk in the default system temp folder (/tmp by default on Linux). In theory that’s great, but in practice, VisualVM becomes painfully slow because it constantly have to do disk I/O’s to process the information.
This behavior is even more frustrating if you happen to have a server with 12 Gigabytes of RAM available for you. A simple solution for that is to create a ramdisk and tell VisualVM to use that ramdisk as the tmp folder.
The solution: use a RAMDisk
First, create the RAMDisk (tmpfs). Here I am on a linux development server and I create a tmp folder in my home. Then I create (mount) the ramdisk in the tmp folder I just created:
$ mkdir /tmp/ramdisk
$ sudo mount -t tmpfs none /tmp/ramdisk
Then I launch VisualVM and I modify the java.io.tmpdir VM arg that tells VisualVM where the system tmp folder is.
$ jvisualvm -J-Djava.io.tmpdir=/tmp/ramdisk
Now VisualVM is much much faster and I can investigate and find the root cause of that memory leak much faster.
After IBM, now is the turn to Oracle. Oracle buys Sun and pays $7.4 billion for that acquisition ($9.50 per share), $5.6 billion if we take into account Sun's cash. Is that a good thing or a bad thing for the Java community? Probably a good thing as it will allow Sun's project to benefit from Oracle's technologies. But only future will tell.
With Java, GlassFish, MySQL, OpenOffice, Solaris and its cloud computing services, that certainly widens Oracle's possibilities. Hopefully Oracle will continue supporting adequately those famous open source projects. I am not concerned about Java, but maybe more about MySQL. While MySQL could certainly benefit from Oracle's expertise in database field, Oracle could also put MySQL behind in order to promote its more profitable flagship product: Oracle's RDBMS. The same is true for GlassFish and WebLogic. In any case, it is a very quick way for Oracle to have an open source offering for their products.
If we only consider Java, I have to admit that I rather see Oracle acquiring Sun than IBM doing it. The reason is simple, IBM already offers a Java runtime and they are competitors in that field. An acquisition by IBM would reduce the competition in that areas, which is always a bad thing for customers. In my opinion, Sun's JVM largely beats IBM's one, but it would still be a bad thing to see one of them die to the benefit of the other.
One nice feature of Java runtime is when you send the QUIT signal to a Java process, it outputs the full thread dump to stdout. To send the that signal, just open a terminal and type:
kill -QUIT <pid>
kill -3 <pid>
Where <pid> is the process Id. This does not terminate the process; all threads will continue doing what they were doing.
That feature can be very useful when the application seems to freeze or when you have a very intermittent issue (intermittent deadlock). With the full thread dump, you can see what every thread was doing at that particular moment. So in case of a deadlock, you will be able to see what monitors and what threads are involved.
This can also be helpful to diagnose performance bottlenecks. Suppose you are load testing an application and it does not deliver the expected throughput, but the CPU usage is not the problem. For instance, with kill -3 you will notice right away that the size of the jdbc connection pool is not big enough and all threads are waiting on it for a connection to free.
One thing people ask me from time to time is how to debug a remote Java application. This can be very useful when you experience problems at customer site, but cannot reproduce them in a development environment. We all know logs files do not always contain all information required to solve the issues. In such case, remote debugging can be very useful.
To start remote debugging, one simply needs to add extra VM arguments to the Java command line:
Then, you can use the remote feature of your IDE to connect to the Java process in using the port specified above (8000). For Instance, in eclipse, you would do:
Run -> Debug Configurations… -> Remote Java Applications -> Create new
In the Host field, you enter the host name or IP of the machine running the Java application. In the Port field, you enter the port specified above (8000).
Note that remote debugging also works nicely with SSH tunnels.