Go

Go

Made by DeepSource

Storing non-pointer values in sync.Pool allocates memory SCC-SA6002

Performance
Major

A sync.Pool is used to avoid unnecessary allocations and reduce the amount of work the garbage collector has to do.

When passing a value that is not a pointer to a function that accepts an interface, the value needs to be placed on the heap, which means an additional allocation. Slices are a common thing to put in sync.Pool. One should store a pointer to the slice instead to avoid the extra allocation.

Bad practice

import (
  "sync"
)

var pool = sync.Pool{
  New: func() any {
    return bytes.Buffer{}
  }
}

func foo() []byte {
  b := pool.Get.(bytes.Buffer)

  b.Reset()
  b.WriteString("something")
  b.WriteByte(' ')
  b.WriteString("something")

  res := b.Bytes()

  pool.Put(b)

  return res
}

Recommended

import (
  "sync"
)

var pool = sync.Pool{
  New: func() any {
    return new(bytes.Buffer)
  }
}

func foo() []byte {
  b := pool.Get.(*bytes.Buffer)

  b.Reset()
  b.WriteString("something")
  b.WriteByte(' ')
  b.WriteString("something")

  res := b.Bytes()

  pool.Put(b)

  return res
}

References