Oops, in that last line I meant to say "then the original caching behavior is preserved." instead of "then the original caching implementation is preserved."
// Paul On Sat, Mar 30, 2024 at 4:35 PM Paul Bjorkstrand <paul.bjorkstr...@gmail.com> wrote: > I didn't see any (public) activity on this, and I had some time to look at > this over this weekend. Here's the ticket [1] and PR [2] that would move > the cache for Resource/Resolver based models into the ResourceResovler > property map. Interestingly, request adaptables already had a similar type > of cache colocation. I just modified the adapter factory's servlet listener > to call close() on the cache when the request object is destroyed. If the > adaptable somehow is neither a Request, Resource, nor Resolver, then the > original caching implementation is preserved. > > This change would also likely close [3] as they are directly related. > > Give it a look and additional testing as needed. > > [1]: https://issues.apache.org/jira/browse/SLING-12279 > [2]: https://github.com/apache/sling-org-apache-sling-models-impl/pull/50 > [3]: https://issues.apache.org/jira/browse/SLING-12259 > > // Paul > > > On Tue, Jan 30, 2024 at 6:36 AM Carsten Ziegeler <cziege...@apache.org> > wrote: > >> Sure, no problem with using a WeakHashMap. >> >> Regards >> Carsten >> >> On 30.01.2024 10:28, Jörg Hoh wrote: >> > Paul, >> > >> > thanks for your mail. I agree to your observation what's going on. I >> also >> > think that cache at the ResourceResolver level makes more sense, and >> it's >> > easier to control and remove cached models, which cannot be used any >> more. >> > >> > @Carsten: Regarding the size, we can still use a WeakHashMap as a >> container >> > for these Sling Models (and store the WeakHashMap in the PropertyMap of >> the >> > ResourceResolver), and that should prevent the worst, even in case of a >> > long-running ResourceResolver or many adaptions. >> > >> > Jörg >> > >> > >> > Am Di., 30. Jan. 2024 um 07:16 Uhr schrieb Carsten Ziegeler < >> > cziege...@apache.org>: >> > >> >> I don't know much about sling models caching, but it seems storing the >> >> cache into the resource resolver and therefore binding it to that >> >> lifecycle sounds very reasonable to me. And due to the mentioned >> support >> >> for Closeable, the cache gets discarded automatically with the resolver >> >> being closed. No extra handling required, no soft references etc. >> needed. >> >> >> >> Obviously, that sounds problematic with long or forever running >> resource >> >> resolvers as the cache would never be released. However, I guess thats >> >> not worse than what we have today. And long running resource resolvers >> >> are an anti-pattern anyway. >> >> >> >> Regards >> >> Carsten >> >> >> >> On 23.01.2024 17:23, Paul Bjorkstrand wrote: >> >>> Hi Jörg, >> >>> >> >>> My guess is that you are running up against the problem where the >> Model >> >> is >> >>> referencing its adaptable, directly or indirectly. In that situation, >> the >> >>> model would not be collectable because it is referenced more strongly >> >> than >> >>> by weak reference. The reference path of these might look like this: >> >>> >> >>> Model Cache Holder (the Model Adapter Factory >> >>> (strong reference) >> >>> Model Cache >> >>> (soft reference) >> >>> Model >> >>> (strong reference) >> >>> Resource Resolver >> >>> (strong reference, maybe indirectly) >> >>> Resource [the adaptable] >> >>> >> >>> >> >>> The resource is strongly or softly referenced, possibly indirectly, >> >> making >> >>> it ineligible for collection on normal GC cycles. The resource & >> >> resolver, >> >>> will not be collected until after the model is collected. Since the >> model >> >>> is not collected until there is memory pressure, that would explain >> why >> >> you >> >>> are seeing this (expensive) GC behavior. >> >>> >> >>> When memory pressure occurs, first the models (soft references) are >> >>> collected prior to the OOM, which releases both resolver (no longer >> >>> referenced via field in the model) and resource. >> >>> >> >>> The quickest fix is to release the resource resolver at the end of the >> >>> model’s constructor or @PostConstruct [2]. Alternatively, you can >> >> eliminate >> >>> the cache=true, provided it does not negatively impact your >> application >> >>> performance. >> >>> Another option, though more involved, is that the entire caching impl >> >> could >> >>> be changed to better handle these kinds of reference loops, by putting >> >> the >> >>> cache in the adaptable itself (Resolver, Resource, Request, etc). >> >> Possible >> >>> good candidates of these are [4] or request attributes. [4] seems to >> be >> >> the >> >>> overall best candidate, especially since you can hook into it using >> >>> Closeable ([5]) improving the cache eviction even more. >> >>> >> >>> As long as the object holding the cache is not referenced strongly >> >> outside >> >>> that reference loop (cache holder > cache > model > ... > cache >> holder), >> >>> then the loop's objects would be eligible for GC as soon as the cache >> >>> holder is eligible. >> >>> >> >>> [1]: >> >>> >> >> >> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >> >>> [2]: >> >>> >> >> >> https://sling.apache.org/documentation/bundles/models.html#a-note-about-cache-true-and-using-the-self-injector >> >>> [3]: >> >> https://github.com/apache/sling-org-apache-sling-models-impl/pull/18 >> >>> [4]: >> >>> >> >> >> https://github.com/apache/sling-org-apache-sling-api/blob/master/src/main/java/org/apache/sling/api/resource/ResourceResolver.java#L888 >> >>> [5]: >> >>> >> >> >> https://github.com/apache/sling-org-apache-sling-api/blob/master/src/main/java/org/apache/sling/api/resource/ResourceResolver.java#L610 >> >>> >> >>> // Paul >> >>> >> >>> >> >>> On Tue, Jan 23, 2024 at 6:48 AM Jörg Hoh <jhoh...@googlemail.com >> >> .invalid> >> >>> wrote: >> >>> >> >>>> Hi Sling community, >> >>>> >> >>>> I want to share a recent experience I had with Sling Models, Sling >> Model >> >>>> caching and Garbage Collection problems. >> >>>> >> >>>> I had a case, where an AEM instance had massive garbage collection >> >>>> problems, but no memory problems. We saw the regular sawtooth >> pattern in >> >>>> the heap consumption, but heavy GC activity (in a stop-the-world >> manner) >> >>>> almost constantly. But no OutOfMemory situation, there it's not a >> memory >> >>>> leak. >> >>>> >> >>>> I manually captured a heapdump and found a lot of Sling models being >> >>>> referenced by the Sling ModelAdapterFactory cache, and rechecking >> these >> >>>> model classes in detail I found them to specify "cache=true" in their >> >>>> @Model annotation.When these statements were removed, the situation >> >> looks >> >>>> completely different, and the garbage collection was normal again. >> >>>> >> >>>> I don't have a full explanation for this behavior yet. The Sling >> Models >> >> had >> >>>> a reference to a ResourceResolver (which was properly closed), but I >> >> assume >> >>>> that this reference somehow "disabled" the cleaning of the cache on >> >> major >> >>>> GCs (as its a WeakHashMap), but tied the collection of these models >> to >> >> the >> >>>> collection of the ResourceResolver objects, which have finalizers >> >>>> registered. And finalizers are only executed under memory pressure. >> >> Having >> >>>> this connetion might have led to the situation that the SlingModel >> >> objects >> >>>> were not disposed eagerly, but only alongside the finalizers in >> >> situation >> >>>> of high memory pressure in a "stop-the-world" situation. >> >>>> >> >>>> I try to get some more examples for that behavior; but I am not sure >> of >> >> the >> >>>> caching of Sling Models as-is is something we should continue to use. >> >> This >> >>>> case was quite hard to crack, and I don't know if/how we can avoid >> such >> >> a >> >>>> situation by design. >> >>>> >> >>>> Jörg >> >>>> >> >>>> -- >> >>>> https://cqdump.joerghoh.de >> >>>> >> >>> >> >> >> >> -- >> >> Carsten Ziegeler >> >> Adobe >> >> cziege...@apache.org >> >> >> > >> > >> >> -- >> Carsten Ziegeler >> Adobe >> cziege...@apache.org >> >