In memory of our loved pointcuts

Using AOP, Spring allows you to easily intercept (or wrap) execution points and “magically” add some particular behavior (an Advice in AOP terms).
Defining the executing points of interest (that is – the “where”) is done using Pointcuts.

Turns out that on a big project like ours with a pretty massive code base, each pointcut defined can be a memory hog as it seems to store information about your code structure in memory.

Using Eclipse Memory Analyzer, I was able to get an insight on the per pointcut memory consumption:

Class Name  		                                                                     | Shallow Heap | Retained Heap | Percentage
------------------------------------------------------------------------------------------------------------------------------------
                                                                                         |              |               |
org.springframework.aop.aspectj.AspectJExpressionPointcut @ 0x5a7a8768                   |           48 |    11,116,288 |      1.14%
org.springframework.aop.aspectj.AspectJExpressionPointcut @ 0x5a7a88b8                   |           48 |    11,113,592 |      1.14%
org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor @ 0x5a7a5318           |           40 |    11,109,328 |      1.13%
org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor @ 0x5a7a61d8           |           40 |    11,105,552 |      1.13%
...

The list goes on and on as we had a lot of pointcuts. Each seems to be accountable for ~11 MB.
Fortunately, most of our pointcuts were hooked up to the same advice so we were able to dramatically reduce the memory consumption by consolidating them as follows:

Before

<aop:config>
		<aop:advisor pointcut="this(com.intelliware.service.IServiceA)" advice-ref="txRequiredAdvice"/>
		<aop:advisor pointcut="this(com.intelliware.service.IServiceB)" advice-ref="txRequiredAdvice"/>
		<aop:advisor pointcut="this(com.intelliware.service.IServiceC)" advice-ref="txRequiredAdvice"/>
	...
</aop:config>

After

<aop:config>
		<aop:advisor pointcut="
			execution(* com.intelliware.service.IServiceA.*(..)) or
			execution(* com.intelliware.service.IServiceB.*(..)) or
			execution(* com.intelliware.service.IServiceC.*(..))"
			advice-ref="txRequiresNewAdvice"/>
		</aop:advisor>
	...
</aop:config>

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply