Enterprise JavaBeans (EJBs)
Enterprise JavaBeans (EJBs) provide the middleware layer of your J2EE application. They come in four flavors:
- Entity Beans
- Stateful Session Beans
- Stateless Session Beans
- Message Driven Beans
Both Entity Beans and Stateful Session Beans maintain some kind of stateful information. An Entity Bean may represent a row in a database or the result of some complex query, but regardless, it is treated as an object in your object-oriented model. Stateful Session Beans, on the other hand, represent temporary storage that exists beyond the context of a single request, but is not stored permanently. Typically, in a web-based application, a Stateful Session Bean's lifetime will be associated with a user's HTTP session. Because their nature is to maintain state, the application server must provide some form of caching mechanism to support them. Simple application servers may maintain a single cache that stores all Entity Beans and Stateful Session Beans, whereas more-advanced application servers provide caches on a bean-by-bean basis.
A cache has a preset size and can hold a finite number of "things." When a request is made for an item, the cache is searched for the requested item: If it is found, it is returned to the caller directly from memory; otherwise, it must be loaded from some persistent store (for example, database or file system), put into the cache, and returned to the caller. Once the cache is full, it becomes more complicated: The cache manager must select something to remove from the cache (for example, the least-recently used object) to make room for the new object. The EJB term used for removing an item from the cache to make room for the new item is passivating, and the term used for loading an item into the cache is activating. If activation and passivation are performed excessively, the result is that the cache manager spends more time reading from and writing to persistent storage than serving requests; this is called thrashing. On the other hand, if the cache manager can locate an item in its cache and return it to the user, the performance is optimal; this is referred to as a cache hit.
When tuning a cache, the goal is to maximize the number of cache hits and minimize thrashing. This is accomplished after a thorough understanding of your application's object model and each object's usage.
Stateless Session Beans and Message Driven Beans are not allowed to maintain any stateful information; a single process may request a Stateless Session Bean for one operation and then request it again for another operation, and it has no guarantees that it will receive the same instance of that bean. This is a powerful paradigm because the bean manager does not have to manage the interactions between business processes and its bean; it exists simply to serve up beans as requested.
The size of bean pools must be large enough to service the requests from business processes; otherwise, a business process will have to wait for a bean before it can complete its work. If the pool size is too small, there are too many processes waiting for beans; if the pool size is too large, you are using more system resources than you actually need.
Another helpful effect of the fact that Stateless Session Beans and Message Driven Beans are stateless is that application servers can preload them to avoid the overhead of loading beans into a pool upon request; the request would have to wait for the bean to be loaded into memory before it could be used.
Two of the most influential tuning parameters of Stateless Session Bean and Message Driven Bean pools are the size of the pools that support them and the number of beans preloaded into the pools.