Monday, January 06, 2014

Case of the runaway Cache System

We are running EhCache in production, and the cache has been configured with Cache size in memory and on the disk.
However, upon analysis of heap dump using Eclipse Memory Analysis Tool (MAT), we noticed the EhCache was using almost 80% of the memory.


Heap Snapshot

Further research of EhCache , and reading forums, we noticed that the open source version of EhCache was a crippleware, with a serious limitation.
Here is what I read from EhCache forums:

As you have noticed the open-source disk stores do not store the entire cache on disk. Instead the values are stored on the disk, and the keys are stored in memory mapped to value objects which reference where on disk the associated value object can be found. This means each on-disk mapping has an associated in-memory overhead equal to it's key-size plus a fixed overhead per mapping. 

Ref: EhCache Forum Post

In conclusion it is very important that unless you are using BigMemory or other commercial caching engines, Open source EhCache , will choke your application. Caveat Emptor !!!




Monday, December 16, 2013

Spring memory leak issue in AntPathMatcher




I manage performance issues on one of the healthcare insurance exchanges. No not Healthcare.gov ..

We recently ran into issue, where under heavy load conditions, the Young nursery is getting filled up, causing excessive garbage collections.

Basically AntPathStringMatcher creates whole bunch of Regular Expressions to match, and further it caches the URLs. Unfortunately the URLs, are filling the cache, and causing memory leaks.

We are using Spring 3.1 

There is a memory issue which has been reported in core spring library.


We applied the patch, and ran a load test simulating 500 users, the number of garbage collections came down 90%.








Thursday, February 08, 2007

Ubuntu Linux: mount_data version 1919251317 is not supported


When u try to samba mount a Windows folder you might get the following error:
mount_data version 1919251317 is not supported

This means that u do not have sambafs insttaled. In order to install, please run the following:
in a terminal window.

sudo apt-get install smbfs




Ubuntu Linux Installed

I am installing Ubuntu Linux 6.0.1 on my Dell Latitude D800. I am using VMWare to virtualize it, which is a very cool thing, as it allows my existing Windows installation to work as it is.
Some of the problems I encountered are with Samba Mount, Setting Screen resolutions right and the like.
As I encounter problems, I will post them here along with solutions or workarounds I used.

Thursday, October 12, 2006

Which ruby postgresql driver should you use?

The following is a snippet from ruby on rails website, as to which postgres driver to use. There are 3, yes three, different postgresql drivers available for ruby (and rails).

1. postgres is old and stale but reliable
2. ruby-postgres is new and improving and beta
it is essentially postgres + improvements
3. postgres-pr is pure ruby, slowest, runs anywhere

For rails 1.0 and 1.1, use ‘postgres’ or ‘postgres-pr’.

For rails 1.1.1 and beyond, try ‘ruby-postgres’ first to see if it works because that will be preferred in the future. You can always fall back to ‘postgres’ if it doesn’t work for you.

‘ruby-postgres’ worked for me..

Thursday, September 07, 2006

Struggling to get POST working with AJAX.Request in Prototype Javascript Library?

Ajax.Request method, in prototype javascript library uses lower case "post" instead of "POST". This is buried deep inside the script.aculo.us documentation wiki .

Wednesday, August 16, 2006

Using Spring DataSourceTransactionManager

QJdbcTemplate qjdb = new QJdbcTemplate();
ds = new DBMSConnection().getDataSource("DataSource");
DataSourceTransactionManager dtm = new DataSourceTransactionManager(ds);
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus trstatus = dtm.getTransaction(def);
try
{
qjdb.setDataSource(ds);
insertSQL();
deletSQL();
// now commit all inserts
dtm.commit(trstatus);
}
catch (Exception dse)
{
dtm.rollback(trstatus);
}

Thursday, March 23, 2006

Solve DB Connection Problems once for ALL


One of the most important problems a database driven application faces is to manage its connections to the database.

Typically these applications use connection pooling. The advantages of pooling are many, connections can be reused , so there is no lag time in serving the connection requested.

But along with this powerful advantage , it becomes critically important that the connection after it has been used , be returned to the pool promptly.

In this article I will be concentrating on how Weblogic manages the DB pools.


A look under the hood:


I was curious to know how a connection pool gets implemented. Especially of interest is how the connection would be returned to the pool , once the connection has been used.

So I decompiled Oracle Java classes “Classes12.zip”.

A closer look at the Connection class shows that , it implements a listener, and hence every time the connection is closed, the listeners are notified, that the connection is closed.


Now in the ideal world for every open connection, there will be a close connection.

And also, in your projects, you make sure that you always have a try-catch-finally block, and close the connections properly. But sometimes, you do not have a choice, and you inherit a code pile from someone. Considering the amount of postings on the internet about conection leaks, it is a common problem. Further you might suspect that there might be some connection leaks lurking in the code somewhere.


Here is a way to solve the problem:


I hope that you have a central object, which handles all the database access and return of connections. Lets call this object DBMSConnection. The DBMSConnection object has two methods , getConnection and safeClose. As the method names suggest, getConnection , with all the internal DB specific plumbing allows you to make a connection from the pool, and safeClose is used to return the connection back to the pool.


public Connection getConnection() throws SQLException {

Connection con = null;

System.out.println("Inside getConnection");

StackTraceElement stke = new Exception().getStackTrace()[1];

String callMethod = stke.getClassName() + "." + stke.getMethodName();

System.out.println("Calling Method: " + callMethod);

return con;


}



/** closes a resultset, a statement and connection in the right order, and

* only if they are not null.

*/

public static synchronized void safeClose (ResultSet resultSet, Statement stmt, Connection connection) throws SQLException {

System.out.println("Inside safeClose");

StackTraceElement stke = new Exception().getStackTrace()[1];

String callMethod = stke.getClassName() + "." + stke.getMethodName();

}



public static void logInTable(boolean insert,String methodName,int hashCode)

throws Exception

{

Connection con=null;

Statement stmt = null;

try

{

con = new DBMSConnection().getConnection();

stmt = con.createStatement();

if (insert)

{

stmt.executeUpdate("INSERT INTO TestConnRelease " +

" VALUES( connectionid_seq.nextval,sysdate,NULL,'" + methodName

+ "','Y',NULL," + hashCode);

}else

{

stmt.executeUpdate("UPDATE TestConnRelease " +

" SET conRel='Y',RelDate=sysdate where " +

"callingMethodName='" + methodName +"' AND hashCode=" + hashCode);

}

}catch(Exception e)

{

e.printStackTrace();

}finally

{

safeClose(null,stmt,con);

}

}