I was using the YourKit Java profiler to investigate some performance issues in our code when doing a series of Hibernate-generated read queries form our code (most of the resulting SQL queries are 8-16kb of SQL, and typically return only one or two rows, but dozens and dozens of columns). Under this load, of all the CPU time being used up by Hibernate, roughly 20% of it (!) was coming from a single stack trace:
{code} sun.reflect.Reflection.getCallerClass() called from
Class.java: line1783 java.lang.Class.getMethod(String, Class[]) called from
ResultSetWrapperProxy.java: line 137 org.hibernate.engine.jdbc.ResultSetWrapperProxy.locateCorrespondingColumnIndexMethod(Method) called from
ResultSetWrapperProxy.java: line 71 org.hibernate.engine.jdbc.ResultSetWrapperProxy.invoke(Object, Method, Object[]) {code}
The line of code in ResultSetWrapperProxy.java: line 137 of org.hibernate.engine.jdbc.ResultSetWrapperProxy.locateCorrespondingColumnIndexMethod(Method) is:
{code} return columnNameMethod.getDeclaringClass().getMethod( columnNameMethod.getName(), actualParameterTypes ); {code}
The basic performance issue here is that ResultSetWrapperProxy.locateCorrespondingColumnIndexMethod(Method) is called often, it's using Java reflection Class.getMethod(String, Class[]) which is slow, and it's not caching the results despite the fact it often frequently repeats the same call parameters on the same class . |
|