Wednesday 30 July 2008

How EXACTLY does garbage collection work in Java?

gc -

main purpose: freeing memory from objects no longer referenced by the program

what does no longer referenced mean?

refcount==0

when is refcount==0? Most profilers use JVMPI or JVMTI (only in J2SE 5.0) to obtain reference counts of objects. MPI == machine profiler interface, MTI == machine tool interface (referring to the Java virtual machine of course).

secondary purpose: combat heap fragmentation (blocks of heap memory in-between blocks of live objects)

designer of each JVM must decide how to implement the gc-collected heap.

benefits:
1. productivity
2. security - prevent programmers from accidentally (or purposely) crashing the JVM by incorrectly freeing memory

What is object equality in Java?

The Object class in Java has two methods that refer to equality: equals() and hashcode(). In general, if you override one of these methods, you must override both, as there are important relationships between the two.

Specifically? If two objects are equal according to equals() they must have the same hashcode() value (reverse not necessarily true).

if o1.equals(o2) then hashcode(o1) == hashcode(o2)

The default implementation of equals() provided by Object is reference equality:

public boolean equals(Object obj) {
return (this==obj);
}

This is a neater way of saying if(this==object) return true; return false;.

By this definition, 2 refs are equal only if they refer to the exact same object.

Friday 25 July 2008

Getting to know java.lang.Object

This is the fundamental class in Java, every Java programmer ought to know it backwards! The Object class has concepts of multithreading, hashing, copy construction and RTTI embedded into it.

An example of RTTI built into the Object class is the getClass method, which returns the runtime class of an object. An example of the copy construction concept built into Object is the clone method.

What does finalize() do in Java?

Every class inherits finalize from java.lang.Object. The method is called by the garbage collector when it determines no more references to the object exist. Should normally be overriden to clean up non-Java resources e.g. closing a file. Good idea to free resources in a try-catch-finally and then call super.finalize(). Finalization is never run more than once on any object. It's generally best to clean resources in a try-catch-finally rather than in finalize() to ensure timely cleanup.

Important note: when an application exits, the JVM will NOT execute finalizers of any object left on the heap. To change this behaviour you need to call the method runFinalizersOnExit, this method is deprecated however as it can result in deadlock.

Objects can be resurrected using finalizers in Java. finalize() is called as an object has no more references. But suppose finalize then adds the object to a static "live" linked list. The object now has an additional reference and can't be garbage collected.

How is a class represented in the JVM?

What happens when I run a Java program?

LLII of the Valley

What happens when you start a Java program can be summarised in four steps (LLII). Loading, Linking, Initialization, Invoke Main. (Ch5 JVM spec covers this in detail).

  1. The bootstrap class loader loads the initial class.
  2. JVM links the class, initializes the class and invokes the main method.

What does loading involve?

Loading involves locating the binary form of a class or interface type (usually the class file format, and constructing a Class object to represent the class or interface). 

The loading process is defined by the class ClassLoader and its subclasses. If an error occurs at the loading stage, a LinkageError will be thrown. An example LinkageError would be a NoClassDefFoundError.

What does linking involving?

"Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type)" (JVMSpec)

Verifying a class means ensuring its binary representation is structurally valid. A VerifyError is thrown if structural constraints on JVM code are violated.  Preparing a class means intialising the static fields to their default values. This does not result in execution of any Java machine code.

What does intializing involve?

Initializing involves init'ing static fields in the class, and any static initializers (procedural code  declared in a static {} scope). There may be other methods that need initialising for example to support Reflection API.

What does executing main involve?

Running the linked program!

Essential reading for Java Programmers