You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@uima.apache.org by "Richard Eckart de Castilho (Jira)" <de...@uima.apache.org> on 2022/03/11 10:52:00 UTC

[jira] [Updated] (UIMA-6413) Memory leak in FSClassRegistry

     [ https://issues.apache.org/jira/browse/UIMA-6413?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Richard Eckart de Castilho updated UIMA-6413:
---------------------------------------------
    Issue Type: Bug  (was: Improvement)

> Memory leak in FSClassRegistry
> ------------------------------
>
>                 Key: UIMA-6413
>                 URL: https://issues.apache.org/jira/browse/UIMA-6413
>             Project: UIMA
>          Issue Type: Bug
>          Components: Core Java Framework
>            Reporter: Richard Eckart de Castilho
>            Assignee: Richard Eckart de Castilho
>            Priority: Major
>             Fix For: 3.3.0SDK, 3.2.1SDK
>
>
> This is essentially a follow-up issue to UIMA-6276.
> So, when a CAS is created, then a cache is filled in {{FSClassRegistry.cl_to_type2JCas}} which maintains information about the JCas representation of the different types. This is a per-classloader cache - so for every classloader which is involved in the creation of a (J)CAS, an entry is added. Now normally, classloaders are pretty long-lived objects and you only have so many during the runtime of a program. But there are cases where classloaders are created in volumes and in this case we run into trouble. Now, UIMA-6276 has turned the cache into a weak map hoping that once a classloader is garbarge-collected, the cache would get cleaned up automatically. However, that idea was not thought through entirely because one of the pieces of information stored in the map is a {{FsGenerator3}} and that generator is actually generated via the particular classloader that is the key in the map. Thus, a value in the map has a strong reference to the weak key causing the key never to get garbage collected... and there might be other fields as well contributing to that cycle.
> In particular, a new classloader is generated whenever a new {{ResourceManager}} with a custom extension path. A typical case for this to happen is when a PEAR is used. But there can be other reasons why somebody would create new custom resource managers.
> Limiting the number of {{ResourceManager}}s in a system may not be feasible because typically there should be one per pipeline (to allow for shared resources), so if you are in a situation where pipelines are instantiated and destroyed repeatedly, it makes sense to create {{ResourceManager}}s alongside.
> However, typically the number of classloaders in a system is pretty set. The {{ResourceManager}} internally wraps these classloaders with an {{UimaClassLoader}} (only if a specific classloader or a extension path is passed to the resource manager). So assuming that essentially always the same set of classloaders is provided (any maybe only a limited set of extension paths), it should be ok to introduce another cache of {{[classloader, extension path] -> UimaClassLoader}} to limit the number of {{UimaClassLoader}} instances and therefore limit the size of {{FSClassRegistry.cl_to_type2JCas}}.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)