adam bien's blog

Dependency Injection Performance in Java EE 6: Dependent (easy) vs ApplicationScoped ("optimized") 📎

Is the simplest possible Java EE 6 Dependency Injection fast enough?

In Java EE 6 you can inject POJOs with @Inject. In this case the lifecycle of the POJO will be dependent on the lifecycle of the injection point. See also Simplest Possible POJO Injection Example With Java EE 6. Injection of POJOs, however, could affect performance: in worst case each request would create a new instance. To test the difference an ApplicationScoped (in fact a singleton) bean will be injected into a Stateless Session Bean as well as a Dependent Scope (an arbitrary POJO) to measure the difference. The code for the application scope bean:

public class Bean {
    public long get() {
        return System.currentTimeMillis();
    }
}

@Path("application")
@Stateless
public class ApplicationScopeTester {

    @Inject
    ApplicationScopedBean bean;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get(){
        return String.valueOf(bean.get());
    }
}

@ApplicationScoped
public class ApplicationScopedBean extends Bean{}


...and dependent scoped:

@Path("dependent")
@Stateless
public class DependentScopeTester {

    @Inject
    DependentScopedBean bean;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String get(){
        return String.valueOf(bean.get());
    }
}

public class DependentScopedBean extends Bean {}


The test was performed with JMeter with the following settings:
500000 Samples, 5 Threads, no think time, with attached VisualVM.

The results are interesting. The performance of the ApplicationScoped bean is only 3.5% better. In most measurements the performance was identical and around 3300 - 3500 transactions / second. Each request was handled by a Stateless Session Bean without any configuration, so each method invocation initiated a new transaction.
The reason for this result is the Stateless Session Bean and its pooling behavior. In Java EE 6 a Stateless Session Bean as a boundary / facade is not only the simplest, but also a reasonable choice.

There was no difference in GC behavior, or CPU usage: CPU Usage 50%, GC Activity 7%, RAM usage 70 MB

ScopeAverageMinMaxTransactions/Sec
Dependent10953248.96
ApplicationScoped10203366.41

The tests were performed with JDK 1.6 Glassfishv3.1 RC2 without any modifications. The entire projects with JMeter load script was pushed into: http://kenai.com/projects/javaee-patterns/, project DependentVsApplicationScopePerformance.
[Thanks Mark Struberg for the idea for this post!]