Saturday, June 6, 2009

uCertify PrepKit for SCJP 5.0

Recently, I got an exciting opportunity to review the uCertify Prepkit for SCJP 5.0 certification.

SCJP stands for Sun Certified Java Professional and is one of the many certifications offered by Sun Microsystems that makes you stand out in the crowd. In the times like these, who would not want that. :-)
If you want to know more about SCJP, you can look at the Sun's site here or you check this to see some related FAQ's.

Coming back to uCertify Preparation Kit, I actually found it pretty useful overall, for it gives you a broad spectrum of features for a relatively smaller price. The preparation engine provides you with
  • Study Notes & Helpful Articles
  • 7 Mock Tests, each with 75 questions
  • Study & Learn Module
  • Ability to Bookmark and Tag Questions
The Study & Learn Module provides a presentation (thus not really boring) based on each Examination Objective of SCJP 5.0. Going through them before the exam could be the fastest way to revise the entire syllabus. This is so because SCJP has well-defined objectives (rules & syntax of the language) that it tests. There is no need to go beyond these objectives if you want to clear the exam.

You can also attach your own notes with Study Notes and Articles, thus making a note of some exceptional condition or some related fact. These makes life really easy when you go through them again.

The practice exams give you a real feel of the actual certification exam as it contains both multiple choice questions (MCQ's) and few drag-and-drop questions. Also the level of the questions are neither too high nor too low. On a personal level, when I took the first practice exam without really preparing for it, I faltered on questions related to in-built classes like Locale, Date, NumberFormat and use of native modifier and Enumerations.

According to me, the best feature is certainly the way the answers are explained once your test is over and you see the results. You can review all the answers whether correct or not, and find out the reason for the same.
The answers are explained in length, touching the concept involved and focussing on why other options are wrong. This gives you a proper insight of what's going on.

On the downside, I would have preferred a highlighting feature that enables me to highlight important facts in the study notes and articles, so that next time I read only that part, which is important to me. Also, I would have loved had they allowed me to copy the code and paste it to test it but I understand that they probably can't do it for piracy issues and misuse.

Conclusion
Although it is an excellent kit to give you a proper feel of the actual exam; it is equipped with some easy ones and some tough(read tricky) questions as well just as the actual paper would. But, do not think that you need just this PrepKit to clear the paper!!
What you also need is a javac(Java compiler) to practice and code. I strongly recommend understanding the involved concepts and coding by hand (not by IDE), then take these useful tests to gain confidence as the actual exam looks almost the same.

For more information about the other preparation kits that uCertify provides you, please visit there site here.

Monday, June 1, 2009

ByteCode Back to Java Source Code !!

I have always thought about the title of this blog entry, ever since I started learning Java. But, until recently, I had no idea about the same. I didn't knew that something magical existed that would perform this conversion. But now since I know a bit, I thought I better share it.

Java Decompiler
As you would have guessed by now, a Java Decompiler is a computer program capable of reversing the work done by a Compiler. In essence, it can convert back the Bytecode (the .class file) into the source code (the .java file).
There are many decompilers that exist today, but we will talk about the most widely used JD - Java Decompiler, which is available both as a stand-alone GUI program and as an Eclipse-plugin.

To install and use these tools are a breeze and would not take you more than a few minutes to get accustomed to it. Hence, I would not repeat the process that's already mentioned on their site.

One thing that we must note here is that the process of conversion might NOT result into 100% exact code, i.e. the generated Java file might not match the actual Java code character by character. However, most of the code would be replicated but things like variable & function names or some other minor details may differ.

Lets have a look at the JD-GUI, stand-alone tool, written in C++;making it pretty fast to execute(decompile) and display the result. Also, it is independent of the the Java Runtime Environment and thus no setup is required to install it.

Lets test the tool now.

Example Java Code:
public class test{
public static void main(String[] args){
System.out.println("Hello world");
}
}


Compile it: javac test.java
so that we have ByteCode (test.class file) with us now.

Decompile it using any one of the following ways:
  1. Execute the following on the command line: jdi-gui.exe test.class
  2. Select 'Open File' from the menu, browse to get to the test.class file and open it
  3. Drag and Drop the test.class file into the JD-GUI tool
All of the above situations result in generating the following Java Code, have a look:

import java.io.PrintStream;

public class test
{
public static void main(String[] paramArrayOfString)
{
System.out.println("Hello world");
}
}

Well just by seeing JD perform really well on this simple example, we cannot decide how efficient is this tool. But, still it is a tool that every Java Developer must be aware of. Because, in case you have accidently deleted your Java files and are left with only the .class files, this is the tool that can save your neck. :-)

Sunday, May 31, 2009

Strings & Java

Perhaps one of the most frequently used Class in Java is the String class. The major reason for Strings to be really poweful is the flexibility of Strings to interact with other objects with so much ease.

Strings in Java posses many unique characteristics that differentiates it from the rest. For example, it is a well-known fact that Strings are Immutable. For those who do not know what that means is, 'String objects one created, can never be changed.' An example would make it more clear.

String s1 = "Hello World";
Here, s1 holds the reference to the String object on the heap containing the value "Hello World". Now, if we type

String s2 = s1.concat(", here I come");
Now, s2 holds another object on the heap with the value "Hello World, here I come". But this doesn't change the object s1. What it rather does, it creates a new object concatenating the new value to it and storing its reference in s2.

If we would have typed,

s1.concat(", here I come");
then also a new object with value "Hello World, here I come" is created but is lost and cannot be referenced since we have not stored it somewhere. Here also, s1 remains the same and is not changed. It cannot be changed.

It would also be good to remember that to make Java Memory Model more efficient,  Java Runtime allocates memory for Strings from "String constant pool" rather than allocating the memory from the heap. 
Now, when the compiler encounters any string literal, it first searches the String constant pool for an identical string. 
  • If a match is found, the reference to the already existing identical string is returned for the new request. 
  • If a match is not found, then a new string literal is created in the pool of strings. This approach works without failure since Strings are immutable in nature.
An example can again smooth things out here:

String s1 = "Agraj";
String s2 = "Agraj";
System.out.println(s1 == s2);              // prints true !!
System.out.println(s1.equals(s2));     // prints true as expected

String s1 = "Agraj";
String s2 = new String("Agraj");
System.out.println(s1 == s2);              // prints false because of 'new'
System.out.println(s1.equals(s2));     // prints true as expected

The first example prints according to String constant pool approach. While, the second example allocates memory again to s2 because the new operator is used, which forces the compiler to allocate memory again.
It would not hurt to remember that the '==' operator is used to compare references while the 'equals' function actually compares the string value(character by character) stored inside the objects.

On some pondering, one might think that if identical strings are not allocated same memory, then if one might change one reference to the string, then all other references would also reflect the change. For example,

String s1 = "Agraj";
String s2 = "Agraj";
s1 = s1.toUpperCase();       // s1 = "AGRAJ" but s2="Agraj"

One might expect s2 also to be equal to "AGRAJ", which is not desired. But, since Strings are immutable in nature, so the toUpperCase() function creates a new string, rather than modifying the original string (it cannot modify the original string, nothing can) and assigns it to s1 while s2 still reference to the original string "Agraj".

StringBuffer and StringBuilder 

A person can argue that in a module that does heavy String manipulation, there would be excess of new Strings that would be created now and then and would not be used at the end, leading to wastage of memory. And you see, this person is not entirely wrong. Strings if used in a careless manner can cause huge performance bottleneck. 
So mostly, when we have to do String manipulation a lot in our application, it is advisable to use classes such as StringBuffer & StringBuilder. Both of these provide the same API and behave in the same manner as Strings do, the difference being the fact that they are mutable. Thus, you can change a StringBuffer / StringBuilder object once created. 
Example:

StringBuilder str1 = new StringBuilder("Hello");
str1.append(" World");

would change the existing object "Hello" and will not create a new object as normal String Object would have done. 

Difference b/w StringBuilder & StringBuffer
Both of them provide us with the same API and thus are similar except the fact that StringBuffer is thread-safe while StringBuilder is not. 
Thus it is always advisable to use StringBuilder class, where-ever thread-safety is not a issue (which is commonly the case always). It is advisable to use StringBuilder than StringBuffer because StringBuilder is much more faster than its thread-safe twin. This is so because it ignores the complications that comes along while deailing with stuff like synchronization and threads. 

There is much more to Strings usage in Java than what can be covered in a blog entry, but I guess I have covered some of the important points which are normally ignored by novices like me. 

Saturday, April 25, 2009

Ergonomics - Garbage Collection in Java

What is Ergonomics ?

With J2SE 5.0 onwards, Ergonomics is defined as the capability of the JVM to
  • Automatically select Heap Size, Garbage collector & type of Virtual Machine (server or client) based on the platform on which your application is running.
  • Allowing us to Tune the behaviour of the Garbage Collector using various command line options to achieve the desired effect. 
But, the aim of Ergonomics is to improve performance & minimize command line tuning as it believes in selecting the optimum configuration for the application which is running. The values are chosen based on the type of machine and the operating system (the platform) on which the application is running.

Machines are divided into 2 categories:
  • Server class machines
  • Non-server class machines
According to J2SE 5.0, a server class machine is the one which has
  1. At least 2 CPU's (processors)
  2. At least 2 GB of physical memory
All other machines with less no of processors and memory are treated as non-server class machines. As visible from the configuration, the server class machines are mostly used to run large applications (typically web applications using some server framework) 

Automatic Selections

For a server class machine, the default values chosen are

Type of JVM : Server JVM
Type of Garbage Collector  : Parallel Garbage Collector
Heap Size :
1/64th of Physical Mem Avail  <=  Min Heap Size  <= 1 GB
1/4th of Physical Mem Avail    <=  Max Heap Size <= 1 GB

For a non-server class machine, the default values chosen are

Type of JVM    : Client JVM
Type of Garbage Collector     : Serial Collector
Heap Size :
Min Heap Size :    4 MB
Max Heap Size : 64 MB

To explicitly make JVM treat your machine as server machine, one can do it using any of the 2 ways:
1. Use the -server command line option with java command
2. Change the first two lines of jvm.cfg file in your JRE_installation_directory/lib/
Change 
-client KNOWN
-server KNOWN
to
-server KNOWN
-client KNOWN

A server JVM differs from client JVM in the sense that it might take more time (approx. 10% more time) in start-up, but eventually it increases the performance & the throughput of the application in the long run. 
While client JVM is sufficient for normal standalone applications, server JVM is best suited for large-scale applications like web applications using a server framework running on some application server.

Behavioral Tuning

If you really know that these automatic settings are not suitable for your application, then JVM gives you the flexibility of changing them as well.

Changing the type of VM
Use -client for using Client VM
Use -server for using Server VM

Changing the type of Garbage Collector
Use
-XX:UseSerialGC Serial Collector
-XX:UseParallelGC Parallel Collector
-XX:UseParallelOldGC Parallel Compacting Collector
-XX:UseConcMarkSweepGC CMS Collector

Changing the Heap Size
Use -Xms to set Minimum heap size. Ex: -Xms512 will set 512MB to be minimum heap size
Use -Xmx to set Maximum heap size. Ex: -Xmx724 will set 724MB to be maximum heap size.

Setting maximum & minimum heap size to be same takes away the flexibility away from JVM of changing the heap size according to the requirements as they arise.

Certain Goals
With these command line options, you can set certain goals for the Garbage Collector to achieve and their relative priorities. The Garbage Collector works to achieve these goals and can change the heap size and other related parameters

Maximum Pause Time Goal
This goal can be used to set Maximum pause time that a Garbage Collector is allowed i.e. we can specify -XX:MaxGCPauseMillis=n meaning that Garbage Collector is allowed a maximum pause time of n milliseconds for each generation. And if it is not able to limit itself to n milliseconds then it must take some measures to achieve this goal. For example, it can reduce the size of the heap in order to reduce the maximum pause time.

Throughput Goal
It can be used to specify the time spend in doing Garbage Collection using -XX:GCTimeRatio=n 
The ratio of garbage collection time to application time is 1/(1+n)
So, that means if we set -XX:GCTimeRatio=19, it means that a maximum of 5% of total time can be spend in Garbage Collection.
Default value is n=99 which means that 1% of  total time is allowed for garbage collection
If this goal is not met, then the size of heap is increased so that it takes more time to fill the heap and thus garbage collection occurs less frequently.

Footprint Goal
This is an interesting one. It specifies that if Maximum Pause time goal and Throughput goal have been met, then keep on decreasing the size of the heap until one of the above mentioned Goals cannot be met. Then try to meet that goal. :-)

Goal Priorities
This goal specifies that priority of above mentioned goals. The order of importance is 
1. Max Pause Time goal
2. Throughout goal
3. Footprint goal

Tools to evaluate GC performace
In an ideal condition, you need not worry about Garbage Collection. This is precisely the goal of Ergonomics; selecting the best possible configuration according to the machine on which the application is running. But if your application runs into memory troubles like memory leaks and OutOfMemoryError, then there exists a plethora of tools to choose from.
Writing about each of them is out of scope of this document. So, I'm just giving out the names and the required links that would help you analyze the application and take proper steps

Some Tools To Look Out for
jConsole (Monitor you App)
HPROF (A Heap/CPU Profiling Tool)
jHat (Java Heap Analysis Tool)
VisualVM (Latest Tool and a Very Good One)
jStack (Stack Trace)
jinfo (Configuration Info)

Disclaimer: The contents of this blog and of all others are totally my personal opinion about the stuff, I have written and has nothing to do with my employer :-)