Thursday, June 24, 2010

Synchronized Map in Oracle driver?

0 comments
I posted this thread on Oracle's forum after finding out that the top monitor in my application was a "SynchronizedMap" in Oracle driver. It seems that each prepared statement needs to access this map, getting worse as one increases the number of database operations in the system.

StringBuilder memory allocation

0 comments
Today I was trying to understand a heap dump for a String that, when saved to a file, had 3 Mb in size. However, its retained dump was over 9 Mb! First, this String was a ThreadLocal variable - a library that we use to marshal this String into XML uses ThreadLocal (a good post on StringBuilders and ThreadLocal here).

A colleague tried to understand why it was 9Mb and found out a couple of things that we were not considering:
  • UTF16: each character consumes 2 bytes in a String to be represented. So, our 3Mb file would consume a minimum of 6Mb of memory space
  • StringBuilder allocation: whenever StringBuilder needs to expand its capacity, it doubles the current allocated memory. So, if we had 4.5Mb and needed one byte more, it would allocate an internal buffer of 9Mb. In our case, it was clear that 3 out of 9Mb had never been used for anything

Wednesday, June 09, 2010

Apache Commons DBCP and initial pool size

0 comments
Unless you are using BasicDataSource, DBCP does not provide an initial pool size, which is very important if you want to avoid pool expansion out of sudden. It is particularly important if you are migrating from C3P0, like what I did recently. So, in this case, you will have to code an initializer to do it for you. In my case, I wrote a static method that is invoked through Spring:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.ObjectPool;

public class DataSourceInitializer {
    private static final Log log = LogFactory.getLog(DataSourceInitializer.class);

    public static void init(ObjectPool pool, int initialSize, String dataSourceName) {
        int count = 0;

        log.info("Initializing connections for data source: " + dataSourceName);

        for (int i = 0; i < initialSize; i++) {
            try {
                pool.addObject();
                count++;
            }
            catch (Exception e) {
                log.warn("Failure to initialize connection.", e);
            }
        }

        log.info("Initialized " + count + " out of " + initialSize
                + " connections for data source: " + dataSourceName);
    }
}
And, in Spring, I call it like this:
<bean id="dataSourceInitializer"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
                depends-on="pollableConnectionFactory">
       <property name="staticMethod"
           value="com.example.DataSourceInitializer.init" />
       <property name="arguments">
           <list>
               <ref bean="objectPool" />
               <ref bean="databasePoolSize" />
               <value>mainDataSource</value>
           </list>
       </property>
</bean>

Tuesday, June 01, 2010

How to bind to all local addresses

0 comments
Whenever we bind to an address, typically we bind to an address and port.
InetSocketAddress local = new InetSocketAddress("localhost", port);
socket.bind(local);
This binds your socket only to "localhost". What if your host has multiple names, such as "localhost" and "myhost.mydomain"? You can still bind to all local addresses by doing the following:
InetSocketAddress local = new InetSocketAddress(port);
socket.bind(local);
Internally, this binds to all localhost addresses by using InetAddress.anyLocalAddress() (which is package private).

Java Thread States

0 comments
We had a little bit of debate last week about Java Thread states and I found the explanation for our questions in the Thread.State javadoc. The main question is the difference between BLOCKED and WAITING, but I guess this subtle difference is clear below:

NEW
Thread state for a thread which has not yet started.

RUNNABLE
Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

BLOCKED
Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

WAITING
Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:

* Object.wait with no timeout
* Thread.join with no timeout
* LockSupport.park

A thread in the waiting state is waiting for another thread to perform a particular action. For example, a thread that has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on that object. A thread that has called Thread.join() is waiting for a specified thread to terminate.

TIMED_WAITING
Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:
* Thread.sleep
* Object.wait with timeout
* Thread.join with timeout
* LockSupport.parkNanos
* LockSupport.parkUntil

TERMINATED
Thread state for a terminated thread. The thread has completed execution.