Performance impact of using CDI - java

I am writing a Java EE 6 web application and I am noticing a significant performance impact when using an injected object versus creating and using the object directly. The overhead appears to be of the order of 50 - 60ms per method call.
For example, using non-injected 150 method calls take approx 500ms whereas using the injected object 150 method calls take 12,000 - 13,000ms. An order of magnitude difference and then some.
Is this usual?
I am running on JBoss AS 7.1.1 final which uses Weld to handle CDI.
The injected object is defined as a singleton bean (via the javax.ejb.Singleton annotation). Could this be causing part of the problem? Or is it just the Weld proxy causing the slow down?

After some help from the excellent Weld forum I have discovered that:
By default, singleton session beans are transactional (section 13.3.7
of the EJB 3.1 specification) and require acquisition of an exclusive
lock for every business method invocation (sections 4.8.5.4 and
4.8.5.5). In contrast, a javax.inject.Singleton is not transactional and does not support container-managed concurrency (the major
consequence being that no locking scheme is implemented by the
container).
If you annotate your singleton session bean with
#TransactionAttribute(NOT_SUPPORTED) and #Lock(READ), you should see
significantly better performance, though there may still be some
overhead. If you don't need EJB features, stick with
#ApplicationScoped (javax.inject.Singleton is not defined by CDI, and
its semantics are therefore not governed by that specification).
https://community.jboss.org/thread/213684?tstart=0
Sadly even after annotating my EJB singleton with #TransactionAttribute(NOT_SUPPORTED) and #Lock(READ) the performance was still very poor (see timings from original post).
So the take home message is don't inject EJB Singleton session beans unless you absolutely have to and even then be aware of the performance overhead that is likely to be incurred. For methods that are rarely invoked it could be negligible but as in our case small overheads accumulate rapidly if it is a heavily used method.
We did not need the EJB features and on switching to ApplicationScoped saw order of magnitude improvements in performance of the specific method that called through to the injected bean.

Related

Stateful session bean passivation and serialization - EJB

Following questions hits my mind
1) I read somewhere:
Passivation: a stateful bean's chance at scalability
What does scalability means here ?
2) How Stateless session bean more scalable then Stateful session bean ?
3) As
For passivation a stateful session bean is serialized and for
activation it will be de-serialized by container ...
Why we do need of serialization and deserialization, can't it (passivaition and activation) be done without serialization and deserialization ? And how serialization helps container to passivate a bean ??
1) stateful session beans must maintain their identity and state between method calls. If such a bean has not been accessed for some time then the container can elect to passivate it. This means its state is preserved somehow outside of the JVM (typically written out to a disk file using java serialization) and it's resource usage (memory) is recovered. The container will activate it again (deserialize it) when the SFSB is accessed again. The SFSB is therefore able to scale better (more "instances" of it can fit in a single JVM, but there is an associated time and I/O penalty).
2) stateless beans need only exist for the duration of single method call, following which any resources that they use can be reclaimed. More commonly a number of them would be maintained in a pool and temporarily made available to deal with a particular method call. As such stateless session beans have little or no direct impact on scaleability.
Stateful session beans are used for quite different purposes than stateless session beans. You would not choose one over the other because of scalability concerns.
3) Serialization is the mechanism that Java uses to read and write arbitrary object state. The instance variables associated with a SFSB must be serializable (aside from some documented exceptions). This not only allows the SFSB to be passivated/activated, but also allows it to be migrated to other JVM instances in order to support fail-over and/or load balancing.
With respect to SFSBs, passivation and activation could be done in other ways, but serialisation is mandated by the EJB specification.

synchronized method in stateless session bean not working as expected in glassfish

I have a war file deployed in glassfish. We have some stateless session beans and we have 1 synchronized method in it.
However, I am noticing that more than 1 thread is able to enter the synchronized method concurrently. Is it possible that glassfish is instantiating 2 instances of this bean class? Is there any way around this?
Yes, of course it's possible. The spec even mandates that concurrent calls are handled by different instances.: this is one of the services offered by the container: it makes sure that concurrent calls are handled concurrently, and not sequentially, and you're free to implement your sesssion bean without caring about thread-safety (for example, by using instance variables), because the container takes care of it.
What you want is a singleton.

Why Stateless EJBs are pooled?

What is the reason why the Application Servers pool the Stateless EJBs?
I can understand that it is usefull to control the workload of the application for incomming invokations, but this only justifies the pooling of the EJBs that server as FAƇADE with the invoker client.
Does it have any benefit to pool the internal EJBs (those that are not exposed and only invoked internally to perform business logic)?? instead of use a shared single instance (like Spring does).
I can think about at least one downside: a highly used internal EJB could act as a bottleneck.
Stateless session bean EJBs are not necessarily thread-safe. They can be holding resources like JMS sessions which cannot be shared with more than one thread at a time so the server will pool them so that it can serve multiple requests for the same bean concurrently (JMS resources are also pooled, but I'm just using that for the sake of example).
I would also like to know why stateless EJBs are pooled. But i want to know why they're pooled rather than being created and destroyed on demand. The fact that instances can be reused for unrelated requests significantly complicates the implementation of stateless beans (it means you have to be incredibly careful about the use of instance fields), and i don't see any significant benefit to it.
Specifically, i don't see any performance benefit to it. I poked through the implementation of stateless beans in JBoss (6, IIRC), and its only the bean instance itself that's pooled; the plumbing to handle method invocation is recreated from scratch each time it's used. That means that the only performance saving is a single object creation, which should be a trivial amount of time. The only situation in which i can see it being non-trivial is if the bean acquires heavyweight resources, and holds on to them between invocations. However, in that case, the bean is really being used as a glorified, badly-managed, pool; the correct solution would be to pool the resource directly!
Now, EJB has been around a long time. Back when they first came out, object creation was expensive, so it made sense to pool them. But those days are long gone. Why was pooling not dropped in EJB3?

multi threaded servlet; single threaded ejb

In a traditional n tier web app with servlets for web layer and ejbs(2.0) for biz layer, what is the rationale behind making the servlet model multi threaded and the ejb model single threaded?
i.e there is only 1 servlet instance for all requests, but for ejbs, for each request, there is a new bean instance assigned from the bean pool.
There is indeed only one instance for a specific Servlet since they are supposed to be stateless. In practice this isn't always the case, but so be it.
There are however multiple instances of Stateless session beans (SLSB), and those are pooled.
By their very definition, stateless session beans are stateless, so on the surface this seems like a paradox. The things is that while stateless session beans are stateless with respect to individual calls being made to them, they in fact very often have state.
This state is in the form of references to other resources. The JPA entity manager, which is not thread-safe, is a prime example here. During a single call to a stateless session bean, the caller must have exclusive access to this resource. When the call returns, the next caller can have exclusive access, etc.
If a single instance was used, then either all callers would have to wait on each other (which is of course killing for performance), or they would have the access this single instance concurrently. In the latter case, the bean implementor has to do manual locking of the non thread-safe resources like the entity manager which is often brittle, error-prone and in the end still causes callers to wait on each other.
So, in order to improve performance and still have the safety guarantee, multiple instances are being used.
Those instances are then being pooled and re-used instead of created fresh for each request, because finding, initializing and injecting all required dependencies of the bean can potentially be time consuming.
All of this thus automatically also means that if you inject an entity manager or other non thread-safe resource into a Servlet (which is allowed), you may run into problems. This is a small loop-hole in the Java EE architecture, which is of course easily worked around by simply making use of stateless session beans.
I think that typically servlets present thin facade to the heavy logic implemented in EJBs. Servlets should be stateless and therefore there is no reason to create more than one instance of the same servlet.
If you are using stateless beans only I think that there is no reason to have more than one instance too. But statefull EJBs have state and therefore you need instance per simultaneous request.
I hope I did not say bullshit.

Why stateless session beans are single threaded?

As per my understanding stateless session beans are used to code the business logic. They can not store data in their instance variables because their instance is shared by multiple requests. So they seem to be more like Singleton classes. However the difference is contain creates (or reuses from pool) the separate instance of stateless session beans for every request.
After googling I could find the reasoning that the Java EE specification says they are suppose to be single threaded. But I can't get the reason why the are specified to be SINGLE THREADED?
The SLSBs are single threaded because of the TX Context, Principal is associated with a bean instance when it is called. These beans are pooled and unless the max pool size is reached are processed in separate threads ( Vendor dependent).
If SLSBs were designed thread safe every call would have looked like a servlet doGet/Post with request info containing Tx Context , Security Context info and etc. So at least the code looks clean (developer dependent).
The primary reason stateless session beans are single threaded is to make them highly scalable for the container. The container can make a lot of simplifying assumptions about the runtime environment. A second reason is to make life easier for the developer because the developer doesn't have to worry about any synchronization or re-entrancy in his business logic because the bean will never be called in another thread context.
I remember the reasoning being discussed in the reviews of the original EJB 1.0 specification. I would look at the goals section of the specification. See http://java.sun.com/products/ejb/docs.html for the list of specifications.

Categories