Skip to content

Commit d3ad749

Browse files
committed
Clean Symbol Tables
Signed-off-by: SungJin1212 <tjdwls1201@gmail.com>
1 parent edd0091 commit d3ad749

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* [BUGFIX] Fix nil when ingester_query_max_attempts > 1. #7369
1010
* [BUGFIX] Querier: Fix queryWithRetry and labelsWithRetry returning (nil, nil) on cancelled context by propagating ctx.Err(). #7370
1111
* [BUGFIX] Metrics Helper: Fix non-deterministic bucket order in merged histograms by sorting buckets after map iteration, matching Prometheus client library behavior. #7380
12+
* [BUGFIX] Fix memory leak in `ReuseWriteRequestV2` by explicitly clearing the `Symbols` backing array string pointers before returning the object to `sync.Pool`. #7373
1213

1314
## 1.21.0 in progress
1415

pkg/cortexpb/timeseriesv2.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ func ReuseWriteRequestV2(req *PreallocWriteRequestV2) {
7777
req.data = nil
7878
}
7979
req.Source = 0
80+
81+
for i := range req.Symbols {
82+
req.Symbols[i] = ""
83+
}
8084
req.Symbols = req.Symbols[:0]
8185
if req.Timeseries != nil {
8286
ReuseSliceV2(req.Timeseries)

pkg/cortexpb/timeseriesv2_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@ func TestTimeseriesV2FromPool(t *testing.T) {
5252
})
5353
}
5454

55+
func TestReuseWriteRequestV2(t *testing.T) {
56+
req := PreallocWriteRequestV2FromPool()
57+
58+
// Populate req with some data.
59+
req.Source = RULE
60+
req.Symbols = append(req.Symbols, "", "__name__", "test")
61+
62+
tsSlice := PreallocTimeseriesV2SliceFromPool()
63+
tsSlice = append(tsSlice, PreallocTimeseriesV2{TimeSeriesV2: TimeseriesV2FromPool()})
64+
req.Timeseries = tsSlice
65+
66+
// Capture backing array before reuse
67+
symbolsBackingArray := req.Symbols[:cap(req.Symbols)]
68+
require.Equal(t, "__name__", symbolsBackingArray[1])
69+
require.Equal(t, "test", symbolsBackingArray[2])
70+
71+
// Put the request back into the pool
72+
ReuseWriteRequestV2(req)
73+
74+
// Verify clearing directly on the backing array
75+
for i, s := range symbolsBackingArray[:3] {
76+
assert.Equalf(t, "", s, "symbol at index %d not cleared", i)
77+
}
78+
79+
// Source is reset to default
80+
assert.Equal(t, API, req.Source)
81+
// The symbol length is properly reset to 0.
82+
assert.Len(t, req.Symbols, 0)
83+
// Timeseries slice is nil
84+
assert.Nil(t, req.Timeseries)
85+
}
86+
5587
func BenchmarkMarshallWriteRequestV2(b *testing.B) {
5688
ts := PreallocTimeseriesV2SliceFromPool()
5789

0 commit comments

Comments
 (0)