Skip to content

Commit 18f8a13

Browse files
gerolf-dajack-berg
andauthored
Fix memory leak in SdkSpan#spanEndingThread (#7984)
Co-authored-by: Jack Berg <johnmberg8@gmail.com>
1 parent ee277ae commit 18f8a13

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkSpan.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ private void endInternal(long endEpochNanos) {
574574
}
575575
synchronized (lock) {
576576
hasEnded = EndState.ENDED;
577+
spanEndingThread = null;
577578
}
578579
if (spanProcessor.isEndRequired()) {
579580
spanProcessor.onEnd(this);

sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkSpanTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ void nothingChangedAfterEnd() {
144144
/* hasEnded= */ true);
145145
}
146146

147+
/**
148+
* {@code SdkSpan.spanEndingThread} prevents concurrent modification of spans while in the ending
149+
* phase such that only {@link ExtendedSpanProcessor#onEnding(ReadWriteSpan)} implementations can
150+
* modify. Here, we verify the thread ref is released so the thread can be garbage collected. This
151+
* is particularly important where processors hold refs to {@link ReadWriteSpan}.
152+
*/
153+
@Test
154+
void end_ReleasesSpanEndingThreadRef() {
155+
SdkSpan span = createTestSpan(SpanKind.INTERNAL);
156+
span.end();
157+
assertThat(span).extracting("spanEndingThread").isNull();
158+
}
159+
147160
@Test
148161
void endSpanTwice_DoNotCrash() {
149162
SdkSpan span = createTestSpan(SpanKind.INTERNAL);

0 commit comments

Comments
 (0)