How JavaConcurrent work in multithreading

Kibana version :

7.10.2

Elasticsearch version :

7.10.2

APM Server version :

1.21.0

APM Agent language and version :
Java
Browser version :
Chrome 79.0.3945.117
Original install method (e.g. download page, yum, deb, from source, etc.) and version :
download page and local setup
Fresh install or upgraded from other version?
No

**

Hello,
This question is related with other topic.

I would like to add "APM context" in custom multithread solution.
I check how that was done in "apm-java-concurrent-plugin" plugin. There is a class JavaConcurrent that add context to Callable or Runnable.

In this plugin there is a instrumentation class for executor co.elastic.apm.agent.concurrent.ExecutorInstrumentation


    public static class ExecutorRunnableInstrumentation extends ExecutorInstrumentation {

        @Nullable
        @AssignTo.Argument(0)
        @Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
        public static Runnable onExecute(@Advice.This Executor thiz,
                                         @Advice.Argument(0) @Nullable Runnable runnable) {
            if (ExecutorInstrumentation.isExcluded(thiz)) {
                return runnable;
            }
            return JavaConcurrent.withContext(runnable, tracer);
        }

        @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false)
        public static void onExit(@Nullable @Advice.Thrown Throwable thrown,
                                   @Advice.Argument(value = 0) @Nullable Runnable runnable) {
            JavaConcurrent.doFinally(thrown, runnable);
        }     
    }

Code in onExecute JavaConcurrent.withContext(runnable, tracer) put object into WeakConcurrentMap

In onExit method this class call JavaConcurrent.doFinally(thrown, runnable); In this method object added by withContext metod is removed only when Throwable object is not null. Question is what about calls without error ? When such objects will be removed?

    public static void doFinally(@Nullable Throwable thrown, @Nullable Object contextObject) {
        needsContext.set(Boolean.TRUE);
        if (thrown != null && contextObject != null) {
            removeContext(contextObject);
        }
    }

I use JavaConcurrent in my plugin, but from debug I see that WeakConcurrentMap is not cleaning and even when thread stop working, object stay in collection.

Thank you for help.