Skip to content

Commit 0bad176

Browse files
authored
Merge pull request #45 from Basekick-Labs/fix/buffer-pool-memory-leak
fix(pool): drop oversized decoder buffers to prevent memory leak (#19)
2 parents bea8641 + 27e5e5f commit 0bad176

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

decode.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ func PutDecoder(dec *Decoder) {
4646
dec.r = nil
4747
dec.s = nil
4848
dec.bsr.data = nil
49-
if dec.buf != nil {
49+
// Keep buf capacity for reuse, but drop oversized buffers to prevent
50+
// the pool from retaining memory from large decode operations.
51+
if cap(dec.buf) > 32*1024 {
52+
dec.buf = nil
53+
} else if dec.buf != nil {
5054
dec.buf = dec.buf[:0]
5155
}
5256
decPool.Put(dec)

types_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,29 @@ func TestNestedMapIntegerKeys(t *testing.T) {
12711271
require.NotNil(t, out2)
12721272
}
12731273

1274+
func TestPoolReleasesOversizedBuffers(t *testing.T) {
1275+
// Issue #19: pooled encoders/decoders should not retain oversized buffers.
1276+
// Marshal then unmarshal a large payload; the pool should drop big buffers.
1277+
large := make([]byte, 64*1024) // 64KB > 32KB cap
1278+
for i := range large {
1279+
large[i] = byte(i)
1280+
}
1281+
1282+
b, err := msgpack.Marshal(large)
1283+
require.NoError(t, err)
1284+
1285+
var out []byte
1286+
require.NoError(t, msgpack.Unmarshal(b, &out))
1287+
require.Equal(t, large, out)
1288+
1289+
// A second marshal/unmarshal of a small value should work without issue.
1290+
b2, err := msgpack.Marshal("small")
1291+
require.NoError(t, err)
1292+
var s string
1293+
require.NoError(t, msgpack.Unmarshal(b2, &s))
1294+
require.Equal(t, "small", s)
1295+
}
1296+
12741297
func mustParseTime(format, s string) time.Time {
12751298
tm, err := time.Parse(format, s)
12761299
if err != nil {

0 commit comments

Comments
 (0)