To disable passivation set the env. var. EJBPassivationTimeout to zero, as in:
% vbj -DEJBPassivationTimeout=0 com.inprise.ejb.Container ...
The container passivates EVERY [-DEJBPassivationTimeout=x] x seconds all instances not currently in a transaction - so the passivation is not synchronized with the last usage of the bean. Session bean passivation is geared towards putting limits on resource usage rather than keeping the persistent storage and the beans cached data always in synch.
There is a separate timeout for the session instance - the amount of time the bean lives in secondary storage before being blown away altogether. To specify a timeout interval for removal of stateful session beans you need to put an XML element in the vendor specific part of the deployment descriptor. (cart example has an illustration)
Consider, as an example, a shopping cart with a session timeout of 60 seconds and a passivation timeout of 10 seconds. Every ten seconds, shopping carts not currently involved in a transaction are written to secondary storage. After 60 seconds of inactivity the shopping cart is blown away.
ITS does support transaction timeouts. There is a way to set the system default timeout, and a global maximum timeout. You will have to consult the ITS docs for details. Thus, using ITS, session beans will timeout after the user transaction times out (t1), then after the session bean passivates (t2), and then after the session bean times out (t3). So an unused session bean, in an idle transaction, will be removed after no more than t1 + t2 + t3 seconds
>>>> EJB LOG >>>> Failure in StateTransitionManager com.inprise.ejb.StateTransitionException: Cannot invoke "afterBegin" on a bean in state: TX_READYIt is not legal for multiple clients to use a stateful session bean. They are single user objects (or at least, non-parallel access objects). Furthermore, the EJB spec says that a container does not have to detect invalid multiple accesses to a stateful session bean, since in the general case, this is not possible.
There are two places where a session bean is created:
1) when newInstance is called on the class (transitioning out of the "does not exist" state).
2) when readObject is called on the object serialization stream (when transitioning out of the "passive"
state)
Note that a new object is created in both cases. However, in the second case, the object's constructor is not called. Thus, there are two places where an object is created, but only one place where it is constructed.
Now just because the container releases the instance, does not mean that the VM garbage collects the instance. We distinguish these counts by "total in memory" (how many are in memory, including both ones that we have references to, and ones that we don't), and "total in use" which is only the count of the number of beans we are hanging on to. It is up to the garbage collector to reduce the "total in memory" down to the "total in use" at its discretion. Basically the GC typically only fires when the VM gets low on memory, so for mostly idle clients, not very often.
There is still a bug in the counters whereby the PASSIVE count is not reliable. You should ignore this counter.
Note that in practice one needs one thread per access to an EJB object, so one will run out of memory for threads long before one will run out of memory for beans, so we believe not bounding or compacting the pool is not a serious problem.