Wednesday, July 18, 2012

ThreadLocal

http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-variable


Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception

Did you ever encounter a java.lang.OutOfMemoryError: PermGen space error when you redeployed your application to an application server? Did you curse the application server, while restarting the application server, to continue with your work thinking that this is clearly a bug in the application server. Those application server developers should get their act together, shouldn't they? Well, perhaps. But perhaps it's really  your fault!
Take a look at the following example of an innocent looking servlet.
package com.stc.test;

import java.io.\*;
import java.util.logging.\*;
import javax.servlet.\*;
import javax.servlet.http.\*;

public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Log at a custom level
Level customLevel = new Level("OOPS", 555) {};
Logger.getLogger("test").log(customLevel, "doGet() called");
}
}
Try to redeploy this little sample a number of times.  I bet this will eventually fail with the dreadedjava.lang.OutOfMemoryError: PermGen space error. If you like to understand what's happening, read on.

The problem in a nutshell

Application servers such as Glassfish allow you to write an application (.ear, .war, etc) and deploy this application with other applications on this application server. Should you feel the need to make a change to your application, you can simply make the change in your source code, compile the source, and redeploy the application without affecting the other still running applications in the application server: you don't need to restart the application server. This mechanism works fine on Glassfish and other application servers (e.g. Java CAPS Integration Server).
The way that this works is that each application is loaded using its own classloader. Simply put, a classloader is a special class that loads .class files from jar files. When you undeploy the application, the classloader is discarded and it and all the classes that it loaded, should be garbage collected sooner or later.
Somehow, something may hold on to the classloader however, and prevent it from being garbage collected. And that's what's causing the java.lang.OutOfMemoryError: PermGen space exception.

PermGen space 

What is PermGen space anyways? The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. The size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize . The default is 64 Mb on the Sun VMs.
If there's a problem with garbage collecting classes and if you keep loading new classes, the VM will run out of space in that memory region, even if there's plenty of memory available on the heap. Setting the -Xmx parameter will not help: this parameter only specifies the size of the total heap and does not affect the size of the PermGen region.

Garbage collecting and classloaders

When you write something silly like
 private void x1() {
        for (;;) {
            List c = new ArrayList();
        }
    }
you're continuously allocating objects; yet the program doesn't run out of memory: the objects that you create are garbage collected thereby freeing up space so that you can allocate another object. An object can only be garbage collected if the object is "unreachable". What this means is that there is no way to access the object from anywhere in the program. If nobody can access the object, there's no point in keeping the object, so it gets garbage collected. Let's take a look at the memory picture of the servlet example. First, let's even further simplify this example:
package com.stc.test;

import java.io.\*;
import java.net.\*;
import javax.servlet.\*;
import javax.servlet.http.\*;

public class Servlet1 extends HttpServlet {
private static final String STATICNAME = "Simple";
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
After loading the above servlet, the following objects are in memory (ofcourse limited to the relevant ones):

In this picture you see the objects loaded by the application classloader in yellow, and the rest in green. You see a simplified container object that holds references to the application classloader that was created just for this application, and to the servlet instance so that the container can invoke the doGet() method on it when a web request comes in. Note that the STATICNAME object is owned by the class object. Other important things to notice:
  1. Like each object, the Servlet1 instance holds a reference to its class (Servlet1.class).
  2. Each class object (e.g. Servlet1.class) holds a reference to the classloader that loaded it.
  3. Each classloader holds references to all the classes that it loaded.
The important consequence of this is that whenever an object outside of AppClassloader holds a reference to an object loaded by AppClassloadernone of the classes can be garbage collected.

To illustrate this, let's see what happens when the application gets undeployed: the Container object nullifies its references to the Servlet1 instance and to the AppClassloader object.

As you can see, none of the objects are reachable, so they all can be garbage collected. Now let's see what happens when we use the original example where we use the Level class:
package com.stc.test;

import java.io.\*;
import java.net.\*;
import java.util.logging.\*;
import javax.servlet.\*;
import javax.servlet.http.\*;

public class LeakServlet extends HttpServlet {
private static final String STATICNAME = "This leaks!";
private static final Level CUSTOMLEVEL = new Level("test", 550) {}; // anon class!

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Logger.getLogger("test").log(CUSTOMLEVEL, "doGet called");
}
}
Note that the CUSTOMLEVEL's class is an anonymous class. That is necessary because the constructor of Level is protected. Let's take a look at the memory picture of this scenario:

In this picture you see something you may not have expected: the Level class holds a static member to all Level objects that were created. Here's the constructor of the Level class in the JDK:
 protected Level(String name, int value) {
this.name = name;
this.value = value;
synchronized (Level.class) {
known.add(this);
}
}
Here known is a static ArrayList in the Level class. Now what happens if the application is undeployed?

Only the LeakServlet object can be garbage collected. Because of the reference to the CUSTOMLEVEL object from outside ofAppClassloader, the  CUSTOMLEVEL anyonymous class objects (LeakServlet$1.class) cannot be garbage collected, and through that neither can the AppClassloader, and hence none of the classes that the AppClassloader loaded can be garbage collected.
Conclusion: any reference from outside the application to an object in the application of which the class is loaded by the application's classloader will cause a classloader leak.

More sneaky problems 

I don't blame you if you didn't see the problem with the Level class: it's sneaky. Last year we had some undeployment problems in our application server. My team, in particular Edward Chou, spent some time to track them all down. Next to the problem with Level, here are some other problems Edward and I encountered. For instance, if you happen to use some of the Apache Commons BeanHelper's code: there's a static cache in that code that refers to Method objects. The Methodobject holds a reference to the class the Method points to. Not a problem if the Apache Commons code is loaded in your application's classloader. However, you do have a problem if this code is also present in the classpath of the application server because those classes take precedence. As a result now you have references to classes in your application from the application server's classloader... a classloader leak!
I did not mentiond yet the simplest recipe for disaster: a thread started by the application while the thread does not exit after the application is undeployed.

Detection and solution

Classloader leaks are difficult. Detecting if there's such a leak without having to deploy/undeploy a large number of times is difficult. Finding the source of a classloader leak is even trickier. This is because all the profilers that we tried at the time, did not follow links through classloaders. Therefore we resorted to writing some custom code to find the leaks from memory dump files. Since that exercise, new tools came to market in JDK 6. The next blog will outline what the easiest approach today is for tracking down a glassloader leak.


ThreadLocal and memory leaks

(imported from http://blogs.codehaus.org/people/avasseur, read comments there)

Last day I realized that using ThreadLocal can be very dangerous when it comes to long running applications and garbage collections.

When you read the documentation of the ThreadLocal, you read that the object put in a ThreadLocal context is associated to the thread, and will be garbaged once the thread is dead.


Each thread holds an implicit reference to its copy of a ThreadLocal as long as the thread is alive and the ThreadLocal object is accessible; after a thread goes away, all of its copies of ThreadLocal variables are subject to garbage collection (unless other references to these copies exist).


So if you use ThreadLocal to store some object instance there is a high risk to have the object stored in the thread local never garbaged when your app runs inside an app server like WebLogic Server, which manage a pool of working thread - even when the class that created this ThreadLocal instance is garbage collected.

To solve this issue, you will probably have to check for it first with a memory profiler tool like JProfiler, and then wrap the value put in the ThreadLocal in a WeakReference.

That did not appears to be obvious while reading the javadoc. Isn't it ?

Saturday, March 10, 2012

Database Systems



Transaction Isolation Levels:- Defines the scope of data visibility between 2 or more concurrent transactions.



READ UNCOMITTED 


Transactions can read uncommitted (garbage/dirty) data. 
Provides higher throughput. No Locking/Synchronization.
Dirty read is possbile.
Not supported in Oracle


READ COMITTED


Transactions can read only commited data but that data can change during the transaction life cycle.
Provides higher throughput/ No locking Synchronization.
On every read you may get different data.
Oracle Database meets the READ COMMITTED isolation standard. 
This is the default mode for all Oracle Database applications.


REPEATABLE READ


Transactions will get the same data (in rows) for every read. But there may be new rows.
No protection against INSERTS from other transactions.
At any point in a trasaction the read rows are locked so on future reads there may be new rows.
High chances of DEADLOCK. Performance hit (Low throughput)
Oracle Database does not normally support this isolation level, except as provided by SERIALIZABLE.


SERIALIZABLE


Transactions lock/synchronize on the table. 
At any point in the given transaction always same data is read. There are no new rows.
Protects against INSERTS from other transactions.
Very High chances of DEADLOCK. Very low throughput.
Oracle Database does not normally support this isolation level, except as provided by SERIALIZABLE.


Practically, transaction isolation level => READ COMMITTED on the database + use SELECT FOR - UPDATE OR TABLE LOCKING (for data synchronization)


http://docs.oracle.com/cd/B13789_01/appdev.101/b10795/adfns_sq.htm#1024753




SELECT FOR - UPDATE


Use it for locking selective rows that you are working on.
The lock is released on commit or rollback.


-------------------------------------------------------------------------------------------------------------------------------------------------------


CURSORS - is a view of data (window of data)


IMPLICIT -  DML's are implicit cursor (Select/update). DB behind the scenes will start a cursor for every SELECT or UPDATE


EXPLICIT - They can be used in the apps like ProC or in Stored Procs etc where you explicityly define a cursor and then provide a query for data selection.




STATIC  - opens a new cursor every time a new query comes in to the DB.


DYNAMIC - Reuses the same cursor for the similar (with parameters) or same queries.
Database System will create such cursors (process) in shared area. By doing this Databases optimize resource allocation by sharing resources.


Statement s = new Connection.createStatement()

Will always create a new static cursor
Database will never spend time looking for whether the cursor (for query) already exists.

Prepared Statement p = Connection.prepareStatement()

Will check with the database if the compiled query (cursor) already exists. If it does then
the database will returns the existing cursor context.
On first run it will always create a new statement since it wont exist.




Sunday, March 4, 2012

Concurency

Context Switches involved in notify notifyAll and conditional notify.

- Conditional Notify () works best.
- A signal from Notify () can be easily missed - see how
- NotifyAll() wakes up all threads and puts them into runnable state. Hence involves context switches (for each thread woken up)


Antipattern

http://en.wikipedia.org/wiki/Anti-pattern#Software_design_anti-patterns

Static Imports (since Java 5.0) 


Static import is a feature introduced in the Java programming language that allows members (fields and methods) defined in a class as public static to be used in Java code without specifying the class in which the field is defined. This feature was introduced into the language in version 5.0.
The feature provides a typesafe mechanism to include constants into code without having to reference the class that originally defined the field. It also helps to deprecate the practice of creating a constant interface: an interface that only defines constants then writing a class implementing that interface, which is considered an inappropriate use of interfaces[1].

import static java.lang.Math.*;

import static java.lang.Math.PI;
For custom constants Create a Constant class 


BINARY semaphore:

DO WAIT : SSC

Synchronize - Spin (while:signal notset to true -> this.wait()) - Clear (set signal to false)

DONOTIFY: SSN
Synchronize - Signal( set signal to true) - Notify


public class QueueObject {

  private boolean isNotified = false;

  public synchronized void doWait() throws InterruptedException {
    while(!isNotified){
        this.wait();
    }
    this.isNotified = false;
  }

  public synchronized void doNotify() {
    this.isNotified = true;
    this.notify();
  }

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


Saturday, March 3, 2012

Garbage Collection

Garbage Collection

Garbage Collection = Object Promotion (Copy phase) + Marking (Compact MArk and Sweep) for collection

In JDK 6 there are three types of garbage collectors:

Serial Collector Single Threaded. 

Entire Garbage collection is done in one thread. Its suitable in 1 cpu machine.
Garbage Collections throughput in a multi-cpu machine is very low. 

Parallel Collector - Garbage Collection is multi-threaded. You can specify the number of threads.
Default value is the number of CPUs. Improves the GC times and throughput as compared to a Serial collector in a multi-cpu machine.

The idea is the Application is completely halted when GC is running. This is stop-the-world-garbage collector

Use this when your app can afford to pause for high times. This will allow the Application to give more throughput. This may not give lowest latency but gives highest throughput since cpu is available 100% until GC.


CMS CollectorGarbage Collection is multi-threaded. You can specify the number of threads.
Default value is the number of CPUs. Improves the GC times and throughput as compared to a Serial collector in a multi-cpu machine.

Concurrent Mark and Sweep. - mark phase and sweep phase.

The idea is this runs concurrently with the app. Mark phase uses very less cpu.

Sweep phase is the time consuming. 

Use this when your app wants low latency and cannot afford big pauses or no down-times or very low to 0 response times are needed from the app.

This will not give highest throughput since since cpu is also engaged in the concurrent GC threads.

Java Heap


                                                  Young Gen                              |Old Gen (Perm Gen)
Eden Survivor 1 Survivor 2   |



Objects are first allocated on the Eden space. They are promoted from Eden space to S1 then to S2 and then to Old Gen.

Eden -> S1 
This is relatively very fast. There is no real promotion?

Young Gen => Old Gen when there is no allocation space left on Young.
When Old Gen is full and cannot allocate space for objects to be promoted from
Young a Major GC is called.

Major GC = involves object destruction (finalize calls) and memory compaction (arranging the live objects contiguously)

Minor GC = Object Promotion

Young Gen is for allocating the newly created objects.

Young Gen:Old Gen ratio can be specified to the JVM.

Ideally, if you know the behavior of the app then you can determine the objects that are created throughout the life cycle of the app. The ones that live longer or through the life of the app
for e.g. caches etc. the Old Gen should be atleast large enough to accommodate them.  For the other transient objects that come and go through the life of the app Knowing their creation behavior and the pattern of how long they live - you can determine how to divide the rest of the space between Young and Old Gen. The goal is to reduce the chances of Major GC calls as much as possible.


Java Heap = Linkedlist of LinkedLists (Object graph limited by Max Heap Size)

Heap Size : Usually Min and Max heap size should be same.


Let the jvm use the entire address space ( requested on startup for the jvm). This will reduce the number of major GC calls initially (when more memory is needed).

Using a smaller Min Heap size will progressively reduce the number of GC calls as the memory requirement grows in size. But the gc calls will be done often initially until all the memory is being used. 

Java utilities : 

jstack -l <pid>

This C:\>jstack
Usage:
    jstack [-l] <pid>
        (to connect to running process)

Options:
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

C:\>jstack -l 292
2012-03-03 17:44:00
Full thread dump Java HotSpot(TM) Client VM (11.0-b15 mixed mode):

"Worker-138" prio=6 tid=0x35c82800 nid=0xb44 in Object.wait() [0x3b1cf000..0x3b1cfb94]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
        - locked <0x05e10958> (a org.eclipse.core.internal.jobs.WorkerPool)
        at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
        at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

   Locked ownable synchronizers:
        - None


jmap


C:\>jmap
Usage:
    jmap -histo <pid>
      (to connect to running process and print histogram of java object heap
    jmap -dump:<dump-options> <pid>
      (to connect to running process and dump java heap)

    dump-options:
      format=b     binary default
      file=<file>  dump heap to <file>

    Example:       jmap -dump:format=b,file=heap.bin <pid>




 num     #instances         #bytes  class name
----------------------------------------------
   1:        726659       78478288  [C
   2:        203312       28493696  <constMethodKlass>
   3:        203312       16281656  <methodKlass>
   4:        660949       15862776  java.lang.String
   5:        328106       15829632  <symbolKlass>
   6:         19521       11986408  <constantPoolKlass>
   7:         19521        9057120  <instanceKlassKlass>
   8:        105091        7067848  [Ljava.lang.Object;
   9:         15915        6887008  <constantPoolCacheKlass>
  10:        195449        4690776  java.util.HashMap$Entry
  11:         23940        4615512  [B
  12:         92234        3980584  [I
  13:         16914        3962112  [Ljava.util.HashMap$Entry;
  14:         51871        3319744  org.eclipse.core.internal.resources.ResourceInfo
  15:         28072        2268280  [S
  16:         20896        2006016  java.lang.Class
  17:         31469        1386112  [[I
  18:         17051        1229088  [[C
  19:         46687        1120488  org.eclipse.core.internal.dtree.DataTreeNode
  20:         28311         992120  [Ljava.lang.String;
  21:         38133         915192  java.util.ArrayList
  22:         27462         659088  org.eclipse.jface.text.Line
  23:         41049         656784  org.eclipse.datatools.sqltools.result.ResultSetRow
  24:         38136         610176  java.lang.Integer
  25:         14605         584200  java.util.HashMap
  26:         12023         577104  org.eclipse.jdt.core.dom.SimpleName
  27:         11607         464280  org.eclipse.ui.internal.navigator.extensions.EvalutationReference
  28:         13974         447168  java.lang.ref.SoftReference
  29:         10908         436320  org.eclipse.jdt.internal.compiler.ast.SingleTypeReference
  30:          3882         434784  org.eclipse.swt.graphics.TextLayout$StyleItem
  31:          1346         430720  <objArrayKlassKlass>



http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html

http://www.javacodegeeks.com/2012/01/practical-garbage-collection-part-1.html

https://weblogs.java.net/blog/2006/05/04/understanding-weak-references