Why Instance Caching Still Drastically Matters?

Santiago Lema from the Google App Engine group tells about his recent experience on GAE with memcache and instances: here.
As you can see, although using specialized caching solutions like memcache will probably make your application more scalable; you should still use the instance caching (or instance pools if you prefer) in some critical points of your application. No matter how much your company's development methodologies are well-defined, when coding you will minor make design decisionsg that means nothing to non-technical person. And even if you are a careful developer who uses best practices and design patterns as required, you may think that an old method like instance caching is unnecessary when you use a optimized caching solution like memcache, ehcache, etc. Well, believe or not, it still has a great impact on the performance. Especially, in points where a bottleneck more likely to be encountered (like data access objects, request handlers, etc.), it can provide a substantial boost on your throughput with a little trade-off with memory footprint. Even better, with newer versions of Java, you can use ThreadLocals to fine tune your object instantation. For example, it is generally a best practice to declare a logger object as "static final" in the begining of the class declaration:


public final class SomeClass {

    private static final Logger LOG = LoggerFactory.getLogger(SomeClass.class);

...
}

With the static modifier, every instance of that class will share the same logger object which may be undesirable when there are several hundreds of instances of this class and you call logging methods frequently in your code. A better approach could be to use a logger instance per thread, which is possible by declaring it a ThreadLocal variable:


public final class SomeClass {


private static final ThreadLocal LOG = new ThreadLocal();


    private static Logger getLogger() {


        /* Ensure that the Logger is initialized */
        if (LOG.get() == null)
            LOG.set(LoggerFactory.getLogger(SomeClass.class));


        /* Return the thread local instance */
        return LOG.get();
    }

...
}

Now, you can call static getLogger() method to get a thread-local Logger instance; so a new Logger instance for every thread will be created and those loggers will log with the shared class name. Although it is not necessary, we created a helper method that initializes the thread-local Logger instance if it is not already initialized; we could also create a helper static class for doing this with different classes. You can also add some thread information with the log message as a best practice or an identifier related to the performed operation, so it will be possible to see which thread was used for that operation at that time.

Comments

Popular Posts