Can Quarkus/CDI ApplicationScoped beans be removed from context or garbage collected at runtime for any reason? - cdi

My understanding is that these beans are simple java objects, but once they have survived being removed at build-time and have been (lazily) initialized, they are held in the context indefinitely and should not be GC-able even if they are idle for long times.
But I was unable to confirm it after running through the 2.0 CDI specs and the bean lifecycle/CDI related Quarkus docs.
Are there any specific cases where this could happen?

So in theory, you can do AlterableContext#destroy(Contextual<?>) - this would remove the contextual instance (i.e. the instance of your #ApplicationScoped bean) from the context, and then it can be garbage-collected if there are no other references.
For example, in quarkus you can do Arc.container().instance(MyApplicationScopedFoo.class).destroy(). This would call the #PreDestroy callback if present, #PreDestroy interceptors if bound, and remove the MyApplicationScopedFoo instance from the application context.

Related

JSTL and bindings in the stateless mode

An excerpt taken from a book,
For a stateless view, the component tree cannot be dynamically
generated/changed (for example, JSTL and bindings are not available in
the stateless mode). You can't create/manipulate views dynamically.
I perfectly understand the concept of going stateless as in a login form.
What I don't understand is the author's point on, JSTL and bindings are not available in the stateless mode. Please elucidate.
The author seems to be confused itself or overgeneralizing a bit too much.
The component tree can certainly still be dynamically generated/changed. This does not depend on stateful/stateless mode. The only difference with stateful mode is that those dynamic actions won't be remembered in JSF state, so they can't be restored in the postback.
It will in stateless mode continue to work fine if those dynamic changes are initiated by a non-user event during view build time, such as #PostConstruct of a request scoped bean referenced via binding attribute, or a postAddToView event listener method. It will simply be re-executed. If the method logic however in turn depends on some user-controlled variables/actions, such as request parameters or actions invoked during previous postbacks, or it is executed too late, such as during the preRenderView event, then it's not anymore guaranteed that the view will during apply request values phase of the subsequent postback become identical as it was during rendering the form to be submitted. In such case, processing the form submit may behave "unexpectedly" different as compared to a stateful view.

How to destroy ViewScope context with JSF 2.2.6?

Each time, I go on a specific jsf page which bean is annotated with #ViewScoped, the heap increase.
How to destroy ViewScope context ? (to destroy all associated objects and clean memory heap)
Upgrading to 2.2.8 give me other errors, so i want to stay with jsf 2.2.6 implementation.
Question is relative to this : "ViewScope context is not destroyed when View Map is destroyed"
So what is the other method to achieve this ? Does it mean ViewScoped have a pegleg and that is not recommended to use it. So what is the alternative when you have a lot info to display and also ajax on the same page ?
I tried this solution too without sucess. (this post looks like the same)
I read that and also that , i have tried #PreDestroy annotation who doesn't work either in ViewScoped.
I don't want to increase too much memory heap of VM.
If i go on the same jsf page handled by a managed bean with a viewScoped, each time the memory increase until application crash.
Garbage Collector is not occuring during session even after multi-postback or if i close definitively the session and wait 5-10 minutes.
NB: #PreDestroy is still called when session is closed.

CDI postconstruct initializing field

Does anyone know whether the initialization of instance fields within a method annotated with PostConstruct is considered to be thread safe? I am not quite sure if i have to make my fields of my ApplicationScoped bean volatile or not so other threads can really see the values...
Thanks for any hints or answers!
I don't have a direct reference to the spec that absolutely guarantees this, but #PostConstruct should be thread safe.
The CDI runtime is fully in charge of creating beans and will only create one instance for a given scope. #PostConstruct runs before the bean is accessible in such a scope or via injection.

CDI Application and Dependent scopes can conspire to impact garbage collection?

We're starting to experiment with implementing our backend services using CDI. The scenario is this:
EJB with #Startup is started when EAR deployed. An ApplicationScoped bean is injected onto this:
#ApplicationScoped
public class JobPlatform {
private PooledExecutor threadHolder;
#Inject #Any
private Instance<Worker> workerSource;
...
The bean also has an Observer method, which, when an event is observed, gets a worker bean from the Instance workerSource and puts it on the threadPool, where it eventually runs to completion.
All working nicely. However... we've started to see garbage collection issues. A JMAP heap histogram shows that there are many of these workers hanging around, un-garbage collected.
We believe that this is down to the combination of CDI scoping. The API page for #Dependant (http://docs.jboss.org/cdi/api/1.0-SP1/javax/enterprise/context/Dependent.html) reinforces more clearly what's in the docs:
An instance of a bean with scope #Dependent injected into a field, bean constructor or initializer method is a dependent object of the bean or Java EE component class instance into which it was injected.
An instance of a bean with scope #Dependent injected into a producer method is a dependent object of the producer method bean instance that is being produced.
An instance of a bean with scope #Dependent obtained by direct invocation of an Instance is a dependent object of the instance of Instance.
So, following this:
The workerSource bean is bound to JobPlatform, and therefore has an ApplicationScoped lifetime
Any worker beans retrieved using that instance are bound to it, and therefore have an ApplicationScoped lifetime
Because the beanstore of the ApplicationScoped context (my knowledge of the terminology gets a bit hazy here) still has a reference to worker beans, they're not destroyed/garbage collected
Does anyone using CDI agree with this? Have you experienced this lack of garbage collection and, if so, can you suggest any workarounds?
The workers cannot be ApplicationScoped, yet the platform has to be. If we were to create a custom WorkerScope (uh ohhh...) and annotate each worker class with it, would that be sufficient to separate the dependency between worker and instance source?
There're also some suggestions at Is it possible to destroy a CDI scope? that I will look at, but wanted some backup on whether scoping looks like a valid reason.
Hope you can help, thanks.
Your understanding is correct. This was an oversight in the spec, and something that will be fixed in CDI 1.1. Instance can have a memory leak just like you've described when used in a long running scope such as SessionScoped or ApplicationScoped. What you will need to do is get a hold of the Contextual or Bean for the instance and destroy it that way.
For what you're doing, and to avoid the memory leak you're best off to use the BeanManager methods to create instances (that way you'll also have a handle on the Bean and can destroy it) instead of Instance.
While looking into implementing Jason's suggested workaround, I found some more resources relating to the issue:
The issue: https://issues.jboss.org/browse/CDI-139 and https://issues.jboss.org/browse/WELD-920
Example beanManager operations:
https://issues.jboss.org/browse/CDI-14?focusedCommentId=12601344&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12601344
or
org.jboss.seam.faces.util.BeanManagerUtils

Reducing JSF Memory Footprint: Relationship between View State and Bean Scope

I am working on a RichFaces-based JSF application that has com.sun.faces.numberOfViewsInSession and com.sun.faces.numberOfLogicalViews parameters set to 1 but has most of the managed beans set to a "session" scope. If reducing the memory footprint is the prime objective (with no significant deterioration to the page rendering times as well), what would be a better option?
Changing the scope to "request" so that the view state is not held for too long (unlike when the scope is set to "session").
I read somewhere that the scope of the beans could have a bearing on the size of the view (and "request" scoped beans may not necessarily be available for GC at the end of the request). I have seen a performance degradation in this case, straightaway though.
Changing the scope to "application" since a number of pages are user-agnostic and don't really change based on the authenticated user. The application scope would result in a singleton and therefore, would the overall memory associated with a bean would be significantly lower as it is not tied to a user?
Also, would this result in the JSF View lingering around for a little too long? If yes, this would make it worse than how it is currently with the session scoped beans.
Last but not the least, there are multiple forms within a view. Could this play a role as well in increasing the memory footprint?
If the beans don't really change for different users and they are going to be needed most of the time set them to Application scope. That way only one instance of the object will be instantiated and all requests will use it.
For objects that are not shared by all users using Request scope should make them eligible for garbage collection immediately instead of hanging around until the user's session expires.
That doesn't mean that the collector will run immediately but when collection is done they will be removed.

Resources