From da8f60d61d4025ef29f47d56200913da71e0d840 Mon Sep 17 00:00:00 2001 From: qiuyucheng Date: Thu, 26 Feb 2026 12:26:44 +0800 Subject: [PATCH] fix(Point): prevent ThreadLocal memory leak in StringBuilder (#1019) Introduced a maximum capacity threshold (64KB) for the cached StringBuilder. If the capacity exceeds this threshold, the StringBuilder is discarded and replaced to prevent Old Gen exhaustion in long-lived threads. --- src/main/java/org/influxdb/dto/Point.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/influxdb/dto/Point.java b/src/main/java/org/influxdb/dto/Point.java index 277ce4c9..1663913d 100755 --- a/src/main/java/org/influxdb/dto/Point.java +++ b/src/main/java/org/influxdb/dto/Point.java @@ -50,6 +50,7 @@ public class Point { }); private static final int DEFAULT_STRING_BUILDER_SIZE = 1024; + private static final int MAX_STRING_BUILDER_SIZE = 64 * 1024; private static final ThreadLocal CACHED_STRINGBUILDERS = ThreadLocal.withInitial(() -> new StringBuilder(DEFAULT_STRING_BUILDER_SIZE)); @@ -554,7 +555,12 @@ public String lineProtocol(final TimeUnit precision) { // setLength(0) is used for reusing cached StringBuilder instance per thread // it reduces GC activity and performs better then new StringBuilder() StringBuilder sb = CACHED_STRINGBUILDERS.get(); - sb.setLength(0); + if (sb.capacity() > MAX_STRING_BUILDER_SIZE) { + sb = new StringBuilder(DEFAULT_STRING_BUILDER_SIZE); + CACHED_STRINGBUILDERS.set(sb); + } else { + sb.setLength(0); + } escapeKey(sb, measurement); concatenatedTags(sb);