1. Java memory model:
    Sun doc
    Great explaination of GC algos - part 1
    Great explaination of GC algos - part 2
    The basic algorithms:Reference counting, mark-sweep, copying, mark-sweep-compact, generational. Concurrent low pause collector:
    Phase 1 (Initial Checkpoint) involves stopping all the Java threads, marking all the objects directly reachable from the roots, and restarting the Java threads.
    Phase 2 (Concurrent Marking) starts scanning from marked objects and transitively marks all objects reachable from the roots. The mutators are executing during the concurrent phases 2, 3, and 5 below and any objects allocated in the CMS generation during these phases (including promoted objects) are immediately marked as live.
    Phase 3: During the concurrent marking phase mutators may be modifying objects. Any object that has been modified since the start of the concurrent marking phase (and which was not subsequently scanned during that phase) must be rescanned. Phase 3 (Concurrent Precleaning) scans objects that have been modified concurrently. Due to continuing mutator activity the scanning for modified cards may be done multiple times.
    Phase 4 (Final Checkpoint) is a stop-the-world phase. With mutators stopped the final marking is done by scanning objects reachable from the roots and by scanning any modified objects. Note that after this phase there may be objects that have been marked but are no longer live. Such objects will survive the current collection but will be collected on the next collection.
    Phase 5 (Concurrent Sweep) collects dead objects. The collection of a dead object adds the space for the object to a free list for later allocation. Coalescing of dead objects may occur at this point. Note that live objects are not moved.
    Phase 6 (Resetting) clears data structures in preparation for the next collection.
    Memory model and its relation to threading/concurrency
    V Good Faqs
    GC algos

    all VM options
    VM Options explained
    VM options
    VM Options


    Huge list of tips and suggestions
    Tips

  2. Online Java books

  3. java perf


  4. byte, short, int, long are all signed data types in Java. When reading data from network or file sometimes need the ability to read/manipulate the data as unsigned.
    Eg. read one byte size as 0xB0 (176 decimal), for calculation it is -80 and not 176. NegativeArraySizeException if use it to read inside an array.
    Solution to get "Unsigned byte":
    byte length = fileReadBytes[xyz]; //say 0xb0
    short unsignedLen = length; //its 0xffb0
    unsignedLen &= 0x00FF;
    


  5. Runtime Exception "IllegalMonitorStateException" The wait/notify protocol can only be used within code that is synchronized. In this case calling code does not have a lock on the object and will thus cause an Exception at runtime. link


  6. Child process is not killed after the parent process is killed/exits.
    Child thread is not killed when the main thread reaches its end. main() waits for child thread to die.
    public class TestLoopThread
    {
    public static void main(String[] args) {
    {
      LoopThread lThread = new LoopThread();
      lThread.start();
    
      //NOTE: if exit() is not present loop thead continues and main thread waits.
      //if exit() present, main thread also exits.
      //System.exit(0);
    }
    
    class LoopThread extends Thread
    {
        public void run() {
            String s= "LoopThread: looping...";
            while(true){
    	        System.out.println(s);
                try {Thread.sleep(500);} catch (Exception e) {;} 
            }
        }    
    }
    
    
  7. JDK profiling support:
    * HPROF (view hprof options: java -Xrunhprof:help)
    * detailed profiling pdf doc. Amazing depth. Excellent.
    * memory leak link (tells how to find if leak in java code or native code)
    * hprof (heap profiler) link
    * another hprof link

    * JProbe freeware: java profiler
    * JProfiler: 10day trail
    JTune HP


  8. Enable profiling in JDeveloper: java -ojvm -XXtimeportNNNN "other Java options" yourMainClass "program arguments"

  9. JavaBean JavaBeans are usual Java classes which adhere to certain coding conventions.
    * Implements java.io.Serializable interface
    * Provides no argument constructor
    * Provides getter and setter methods for accessing it's properties
    public class SimpleBean implements java.io.Serializable {
    	private String name = null;
    
    	/* Empty Constructor */
    	public SimpleBean() {}
    
    	/* Getter and Setter Methods */
    	public String getName() {
    		return name;
    	}
    	public void setName(String s) {
    		name = s;
    	}
    }
    

  10. We can modify the String args passed to main(String args[]).
    args = new String[] { "cruel", "world"};

  11. Java memory leak
    * Item 5: Eliminate obsolete object references (Effective Java by Bloch)
    When to null out a reference? Collection classes like HashMap, List, etc. manage their own memory. The storage pool consists of the elements of the items set (only references). The elements in the active portion of the array are allocated, and those in the remainder of the array are free. The garbage collector has no way of knowing this; to gc all of the object references in the items set are equally valid. Only the programmer knows that the inactive portion of the array is obsolete reference.
    Whenever a class manages its own memory, the programmer should be alert for memory leaks.

    * Whenever listeners are added, in the end remove the listeners, so that reference to the object that is listening is removed.

    * Item 6: Avoid finalizers (Effective Java by Bloch)
    Finalizers are unpredictable, often dangerous, and generally unnecessary. It can take arbitrarily long between the time that an object becomes unreachable and the time that its finalizer is executed.
    Instead, provide an explicit termination method. Examples: InputStream and OutputStream have close(). java.util.Timer has cancel(). java.awt has Window.dispose() and Graphics.dispose(). Image.flush(). Ignoring these methods causes dire performance consequences.

    * Heap profiling: to check for potential memory leaks.

    * object cycling involves creating and destroying objects rapidly. In such case its useful to implement object cache in application.
    link

    * Use weak references A weak reference is a holder for a reference to an object, called the referent. With weak references, you can maintain a reference to the referent without preventing it from being garbage collected. link
    other nice links at IBM

  12. clone()
    The default protected clone does a shallow copy, that is, it does not make copies of objects pointed to by the object, but it copies all fields and references in an object. If you write your own clone, you might implement a deep copy, that is, also make copies of objects pointed to, and also objects pointed to by those objects recursively. Be careful. It is easy to create a chain reaction explosion or even an endless loop with a deep copy. Clone returns an Object not the type of the thing cloned. You need to cast it back.
    If you are an assembler programmer you can think of clone as implemented by a native method that allocates a block of ram the same size as the existing object, then does a byte block move to copy the object literally byte for byte, then returns a handle to that new ram. I would like to see a variant of this sort of fast object construction for copy constructors. e.g. constructors of the form: view
    Clone property:

    The only strict principles that you must follow for clone are:

    Clone Equality
    If we set y = clone(x), then x.equals(y).
     
    Clone Independence
    If we set y = clone(x), then no method on y can cause the value of x to be modified.

    This is what is known as a safe clone. There are cases where it may make sense to provide what is called a shallow clone, especially with collection classes. Such a shallow clone only duplicates the top-level structure of the object, not the lower levels. A shallow clone is useful in many circumstances so long as programmers can somehow still implement a deep clone on top of those objects. Ideally, such classes would implement both with different names.

    A safe clone is different than a deep clone, which copies the object and all of its fields recursively. A safe copy does not need to copy any field that is irrelevant to Clone Independence. For example, a String field does not need to be cloned. Because Strings are immutable, even if one String is shared by two objects, the contents of the string cannot be changed, and thus cannot break Clone Independence. Similarly, if a field cannot be altered through the class API, then it can be shared between two objects without breaking Clone Independence.




1