Skip to content

Memory leak as a result of no cleanup for ThreadLocal in CodedOutputStream?? #7083

@asclark109

Description

@asclark109

Discussed in #7082

Originally posted by asclark109 February 7, 2025
I am using the io.opentelemetry:opentelemetry-exporter-common:1.38.0 jar in my java web application project running on Tomcat 10. I am getting memory leaks at application shutdown (one is a io.netty.util.internal.InternalThreadLocalMap that is tracked in Netty). The other appears below.

07-Feb-2025 12:36:08.735 SEVERE [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [agtest-trunk] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@658c5a19]) and a value of type [io.opentelemetry.exporter.internal.marshal.CodedOutputStream.OutputStreamEncoder] (value [io.opentelemetry.exporter.internal.marshal.CodedOutputStream$OutputStreamEncoder@421e361]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

I have looked at your class in release 1.38.0 and on main: CodedOutputStream.java

I notice that a ThreadLocal is created and updated but never cleaned up (i.e. there is no call to do THREAD_LOCAL_CODED_OUTPUT_STREAM.remove()).

private static final ThreadLocal<OutputStreamEncoder> THREAD_LOCAL_CODED_OUTPUT_STREAM =
new ThreadLocal<>();
/**
* Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream}.
*
* <p>NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or modify
* the provided byte arrays. Doing so may result in corrupted data, which would be difficult to
* debug.
*/
static CodedOutputStream newInstance(final OutputStream output) {
OutputStreamEncoder cos = THREAD_LOCAL_CODED_OUTPUT_STREAM.get();
if (cos == null) {
cos = new OutputStreamEncoder(output);
THREAD_LOCAL_CODED_OUTPUT_STREAM.set(cos);
} else {
cos.reset(output);
}
return cos;
}

If someone can offer help to get around this (or patch a fix), it would be appreciated. thanks.

Only discussion page I could find on ThreadLocals #6584

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions