Tuesday, April 24, 2007

Java - Call by Value.

Revisiting the famous question - In Java, objects are passed by "Call by Value" or "Call by Reference" ? Many people say it is "Call by Reference" which is wrong based on Programming Languages Theory. The explanation can't be any better than this:

-------- Begin ---------
All parameters to methods are passed "by value." In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments. If you pass a double to a method, its parameter is a copy of whatever value was being passed as an argument, and the method can change its parameter's value without affecting values in the code that invoked the method. For example:
 class PassByValue {
public static void main(String[] args) {
double one = 1.0;

System.out.println("before: one = " + one);
halveIt(one);
System.out.println("after: one = " + one);
}

public static void halveIt(double arg) {
arg /= 2.0; // divide arg by two
System.out.println("halved: arg = " + arg);
}
}

The following output illustrates that the value of arg inside halveIt is divided by two without affecting the value of the variable one in main:
before: one = 1.0
halved: arg = 0.5
after: one = 1.0
You should note that when the parameter is an object reference, the object reference -- not the object itself -- is what is passed "by value." Thus, you can change which object a parameter refers to inside the method without affecting the reference that was passed. But if you change any fields of the object or invoke methods that change the object's state, the object is changed for every part of the program that holds a reference to it. Here is an example to show the distinction:
 class PassRef {
public static void main(String[] args) {
Body sirius = new Body("Sirius", null);

System.out.println("before: " + sirius);
commonName(sirius);
System.out.println("after: " + sirius);
}

public static void commonName(Body bodyRef) {
bodyRef.name = "Dog Star";
bodyRef = null;
}
}

This program produces the following output:
before: 0 (Sirius)
after: 0 (Dog Star)
Notice that the contents of the object have been modified with a name change, while the variable sirius still refers to the Body object even though the method commonName changed the value of its bodyRef parameter variable to null. This requires some explanation.

The following diagram shows the state of the variables just after main invokes commonName:

______________
main() | |
sirius------->| idNum: 0 |
| name --------+------>"Sirius"
commonName()----->| orbits: null |
bodyRef |______________|

At this point, the two variables sirius (in main) and bodyRef (in commonName) both refer to the same underlying object. When commonName changes the field bodyRef.name, the name is changed in the underlying object that the two variables share. When commonName changes the value of bodyRef to null, only the value of the bodyRef variable is changed; the value of sirius remains unchanged because the parameter bodyRef is a pass-by-value copy of sirius. Inside the method commonName, all you are changing is the value in the parameter variable bodyRef, just as all you changed in halveIt was the value in the parameter variable arg. If changing bodyRef affected the value of sirius in main, the "after" line would say "null". However, the variable bodyRef in commonName and the variable sirius in main both refer to the same underlying object, so the change made inside commonName is visible through the reference sirius.

Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory. If the Java programming language actually had pass-by-reference parameters, there would be a way to declare halveIt so that the preceding code would modify the value of one, or so that commonName could change the variable sirius to null. This is not possible. The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.

-- Arnold, K., Gosling J., Holmes D. (2006). The Java™ Programming Language Fourth Edition. Boston: Addison-Wesley.

-------- End ---------

Source: http://forum.java.sun.com/thread.jspa?threadID=719862&messageID=4155502

Monday, April 23, 2007

Using JHAT tool to analyze process running on JDK5.

JHAT is available only with JDK6. However it is possible to use this tool for analysis of a process running on JDK6.

Steps to use HAT tool on JDK5 in association with jHAT on JDK6.
**********************************************************

1. setup environment variables
------------------------------
$ export SA=/net/${JDK5_HOST}/tools/bin/sa15
$ export SA_HOME=/net/${JDK5_HOST}/tools/bin/sa15
$ export SA_JAVA=/net/${JDK6_HOST}/usr/jdk/entsys-j2se/bin/java

2. verify variables are set correctly
-------------------------------------
$ echo $SA ; echo $SA_HOME ; echo $SA_JAVA
/net/${JDK5_HOST}/tools/bin/sa15
/net/${JDK5_HOST}/tools/bin/sa15
/net/${JDK6_HOST}/usr/jdk/entsys-j2se/bin/java

3. generate preload_mappings thru dbx
-------------------------------------
$ /net/${JDK5_HOST}/${DBX_HOST}/bin/dbx -xexec32 -s dbxrc
(dbx) source /net/${JDK5_HOST}/tools/bin/dbxscripts/gen_pm.txt
(dbx) gen_pm
preload_mappings have been generated.
(dbx) quit

4. Generate core file using gcore to a running pid for processes that have not dumped core.

5. Use heapdumpproc.sh to generate heap.bin
--------------------------------------------
$ /net/${JDK5_HOST}/tools/bin/sa15/heapdumpproc.sh executable corefile

6. Start the http server
------------------------
/net/${JDK6_HOST}/${JAVA_HOME}/bin/jhat heap.bin

7. Review the heap dump at http://localhost:7000 - This is the default port.

Note:
------
* Results reported by this approach on JDK5 JVM may not be 100% accurate.
* The results are more accurate if the core is generated by a process crash instead of using gcore on a running pid.

Handling memory leaks in Java

Good discussion on handling memory leaks in Java using a real use case.
http://www-128.ibm.com/developerworks/java/library/j-leaks/

Saturday, February 24, 2007

Synchronizing static methods

In Java, a lock can be obtained on the instance of a class or on a class itself.

We use lock on a class to synchronize static methods instead of lock on an object. Assume I have a private static data member of a class say staticData which is protected by synchronized static method staticFoo. If two threads t1 and t2 try to enter this critical section - staticFoo, Java language provides support to make sure only one thread is in the critical section. But we cannot prevent thread t3 that operates on instance of that class and modifies private static data member staticData. This means the MT-Safe protection is lost.

The solution to this problem is more of a coding discipline not to access static data members directly in object instances of the class if static data members are protected by synchronized static methods. We cannot really enforce it. This reminds me of a famous statement "Design should be open for extension but closed for modification". This is not the case here. Can you associate this problem to Singleton?

Thursday, February 22, 2007

Scheduling in Java

The classic ways of sharing processor by various threads is Preemptive Scheduling and Time Slicing.

Some designs based on Pipeline work model can be well achieved with Preemptive Scheduling. Designs based on Pool of Workers that execute independent tasks can be well achieved with Time Slicing model. The type of scheduling is also influenced by the support offered by OS for multi-threading.

Java as a language is platform independent and does not allow user to dictate on type of scheduling to use for that particular application. Even though it is possible to specify priorities for a thread, the question of honoring priorities is subject to a particular JVM implementation and the respective OS. We have to believe that the JVM is best designed to give optimal performance for all applications irrespective of their design paradigm.

Wednesday, February 21, 2007

Double Checked Locking for Singleton

This turns out to be an anti-pattern unless used properly with volatile or full method getInstance() synchronization.

http://en.wikipedia.org/wiki/Double-checked_locking

Starting and Stopping Threads...

Usage of Thread.stop(), Thread.resume(), Thread.suspend() and Thread.runFinalizersOnExit() is not encoraged. We should use the following pattern to stop threads. Refer to links:
http://java.sun.com/j2se/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
http://www.forward.com.au/javaProgramming/HowToStopAThread.html

Saturday, February 10, 2007

Good book on Java Concurrency

Java Concurrency in Practice (Paperback)
by Brian Goetz (Author), Tim Peierls (Author), Joshua Bloch (Author), Joseph Bowbeer (Author), David Holmes (Author), Doug Lea (Author)

Java design patterns - tutorial

Download tutorial on design patterns in Java from James W. cooper :
http://www.ebooksportal.org/2007/01/java-design-patterns-a-tutorial-addison-wesley.ebp