Saturday, 12 March 2016

Thread Analysis in Java

In my previous article, we had seen a method for analyzing the Heap so as to avoid memory leakage. In this article, we will discuss a methodology for Thread Analysis.

Introduction -
A Multithreaded Java Application handling a large number of Concurrent Users needs to be designed and implemented carefully so as to use the maximum resources available and to reduce the response time for each and every User. By maximum resources, I mean maximum CPU power available at disposal.

But if two or more threads utilize the same resources then a conflict between the threads is inevitable.Thread conflict occurs when a thread is waiting for a lock, held by another thread to be lifted.

A Special type of Thread conflict is a “Deadlock” wherein two or more threads are waiting for other threads to complete their tasks in order to complete their own tasks.

To analyze such issues it is important to know the Thread Status of each and every Thread.
Also in case of an application employing waits and synchronization and facing with random issues like unresponsiveness, slow processing, etc. proper Thread Analysis can help to track the root cause.

We will now see a methodology for Thread analysis using jvisualvm.

Thread Analysis Use case-
  • We will first write a sample program (Console Application) in which we will implement a wait on a thread.
  • We will then run the program and use the Tool jvisualvm to visualize the thread.

1) The Sample program
Class - TestClass
fig. 1. A Sample Class implementing a wait and notify.

As seen above we have implemented a wait on the lobjSynchronizer object in TestClass. Notice the wait is inside a synchronized block so that only one thread can access the code in the synchronized block at a time. 

At the same time we have initiated a separate thread to accept an input from the user and if it is “Y” then we notify the lobjSynchronizer object in a synchronized block due to the reason mentioned earlier.

Class - ThreadMonitorDemo

fig. 2. A Sample Class with main starting TestClass on a new Thread

2) Run the program and start the jvisualvm tool as explained in the earlier post.
2.1 Before Wait
On running the program the console will display a message -
Before Wait.
Enter ‘Y’ to Resume.


This is a State where one Thread (Thread-0 as shown in image below) is in the waiting state and another thread is ready to accept the input from the User.This can be observed in the Java VisualVM tool as shown below.

Thread-0 with the Yellow timeline is the Thread which has encountered the wait on the lobjSynchronizer object in TestClass.

Thread-1 with the Green timeline is the Thread which is ready to accept an input from the User.
ThreadWaitingCropped
fig. 3. Java VisualVM tool snapshot showing Thread-0 in Wait state and Thread-1 in Running State.

Different Thread States as shown in the Tool :
The Thread tab shows a list of live and finished threads. Colors are used to distinguish between different thread states.
  • Running: thread is still running
  • Sleeping: thread is sleeping (method yield() was called on the thread object)
  • Wait: thread was blocked by a mutex or a barrier, and is waiting for another thread to release the lock
  • Park: parked threads are suspended until they are given a permit. Unparking a thread is usually done by calling method unpark() on the thread object
  • Monitor: threads are waiting on a condition to become true to resume execution

The Wait on Thread-0 can also be analysed and seen using the ThreadDump as shown below. (Note to get the Thread Dump click the Thread Dump button in the top right corner of the Threads tab)
ThreadDumpFinal
fig. 4. Java VisualVM Thread Dump showing Thread-0 in Wait state at line 26 in Testclass.java.

2.2 After Wait
Now enter “Y” in the console so that the lobjSynchronizer object is notified and the wait on Thread-0 is lifted.
ThreadRunningCropped
fig. 5. Java VisualVM tool snapshot showing Thread-0’s transformation from Wait state to Running State and Thread-1 completing it’s task.
As seen above the Thread-0’s timeline has transformed from Yellow to Green which means it is now in a running state.

The print statement after wait is also printed on the console and now it is executing a while loop after Wait.

Also notice that the Thread-1’s timeline has transformed from Green to White which means it has completed it’s task (since the inline thread has no task after notifying the lobjSynchronizer object)

Conclusion -
Thread Analysis is an important part of Java Application Development and Java VisualVm provides an effective graphical way for the same.

Hope this will help you in Thread analysis of Java programs.



Wednesday, 2 March 2016

Garbage Collection in Java : Overview and Analysis methodologies

Introduction -
In a programming language such as C, memory allocation and deallocation is a manual process and in the long run can become a tedious task for developers. 

On the other hand, Java has an in-built Memory management system in which the process of deallocating memory is handled automatically by the Garbage Collector. This allows Developers to code without worrying explicitly about memory allocation and deallocation because the Garbage Collector reclaims the memory for reuse.

Garbage Collection in Java -
In Java, there are basically two areas of memory -
  1. Stack - where method invocations and local variables live.
  2. Heap - where objects live.
Garbage Collector basically governs the Heap.

In Java, Garbage Collection is the process of analyzing the Heap memory, identifying which objects are in use and which are not, and deleting the unused objects. 

Now the question arises how is the usefulness / uselessness of an object decided. So the general rule of thumb says that, as long as an object is being referenced, the JVM (Java Virtual Machine) considers it alive and useful; once an object is no longer referenced the JVM considers it as useless and marks it eligible for Garbage collection.

It is a general misconception that the Garbage Collector collects and discards dead objects. But in reality, the Garbage Collector does the opposite by tracking the Live objects and marking everything else as garbage.

Avoiding the Pitfall -
Despite the state of the art Memory management system of Java, it is sometimes possible for Java Applications to suffer from Memory leak issues which can be caused by a number of reasons. 

One of them being, a Logical Memory Leak. It is a case wherein unused objects are still holding references and are still reachable by an Application because the developer simply forgot to dereference them. Such objects cannot be garbage-collected. 

So developers must pay special attention to analyze their code and confirm that their code doesn’t suffer from a Logical Memory Leak. (A visual tool to help in the analysis is described later)

Tools for monitoring JVM -
The JDK provides a number of tools for monitoring the JVM like “Java Management & Monitoring Console”, “Java VisualVM” etc. 

Those tools can be accessed using the Executables in the bin folder of your jdk. If the JAVA_HOME is set then these tools can be accessed directly by executing the necessary commands in the terminal.

Example - command “jconsole” for Java Management & Monitoring Console and “jvisualvm” for Java VisualVM. (We will see a working example of Java VisualVM shortly.)

Garbage Collection in Action -
  • We will first write a sample program (Console Application) in which we create 2 Objects, then derefer one of them unconditionally and the other one conditionally.
  • We will use the “Java VisualVM” to analyze the objects on the heap at each stage.

1) The Sample program
GCDemoFinal
fig. 1. Sample program for demonstrating dereferencing of objects.
Run the above Sample console application.

The Application will keep on running due to the while loop until we stop it.

As you can observe above the object “lobjTestClass1” is dereferred directly by setting it to null and the object “lobjTestClass2” is dereferred conditionally only when user enters “delete” in the console.

Note - 
The Classes “TestClass1” and “TestClass2” are sample classes without anything in them.

2) Heap Analysis
2.1 Open “Java VisualVM” from Terminal using jvisualvm command
jvisualvmFinal
fig. 2. Type jvisualvm command in Terminal (The Terminal shown is a Ubuntu Linux Terminal. Same command can be used in command prompt in Windows)
Note -
If the JAVA_HOME is set then we can directly execute the command as show above.
If JAVA_HOME is not set then we can browse to the bin folder of jdk and execute the jvisualvm executable

2.2 Analysis using Java VisualVM
2.2.1 Once the Java VisualVM Tool is opened Double Click the name of the Java Application in the Applications Tab as shown.
SelectAppFinal
fig. 3. Select the Java application in Applications Tab.

2.2.2 Select the Sampler Tab and Click the Memory button
SelectSamplerFinal
fig. 4. In the Sampler Tab click the Memory Button to get the Heap Histogram.
Tip - 
To find out the required objects quickly sort the Heap histogram on Class Name column.

As seen in the Heap histogram, the object “lobjTestClass1” of Class TestClass1 and the object “lobjTestClass2” of Class TestClass2 can be seen as highlighted above. (Note - We actually cannot see the variable name here but can see the Class name and the number of instances as 1)

2.2.3 Perform Garbage Collection explicitly.
Click on the “Perform GC” button to enforce Garbage Collection. 

Once Garbage Collection is done the object “lobjTestClass1” of Class TestClass1 will disappear from the Heap histogram.

GC1Final
fig. 5. Object of Class TestClass1 has disappeared from the Heap Histogram.
As seen in the Heap histogram, the object “lobjTestClass1” of Class TestClass1 is not seen since it was dereferenced in the Sample program and hence garbage collected by the JVM.

On the other hand, the object “lobjTestClass2” of Class TestClass2 is still on the heap (since it is not dereferred yet) and can be seen as highlighted above.

2.2.4 Enter “delete” in the Application Console
This will derefer the object “lobjTestClass2” of Class TestClass2 since we have set the variable “lobjTestClass2” to null.

Since the variable “lobjTestClass2” is set to null the object on the heap becomes orphan and eligible for Garbage collection.

2.2.5 Again Perform Garbage Collection explicitly.
Once again click on the “Perform GC” button to enforce Garbage Collection.

GC2Final
fig. 6. Object of Class TestClass2 has also disappeared from the Heap Histogram.
As seen in the Heap histogram, the object “lobjTestClass2” of Class TestClass2 is not seen since it was dereferenced in the Sample program and hence garbage collected by the JVM.

Conclusion -
To conclude, we have seen an overview of Garbage Collection in Java, some possible pitfalls, a way for dereferencing objects and a way to visualize and analyse the heap. 

Hope this will help you in writing memory efficient Java programs.