title: When should I put object back to sync.Pool
body: <p>I'm passing a big object via channel between goroutines, one goroutine for publishing, many goroutines subscribe and wait for messages, it's so frequent that I wanna use <code>sync.Pool</code> to reduce the number of allocations, example code like this:</p>
  <pre><code>package main
  
  import (
      &quot;log&quot;
      &quot;sync&quot;
      &quot;time&quot;
  )
  
  var pool *sync.Pool
  
  type object struct {
      info string
      // other stuff
  }
  
  func initPool() {
      pool = &amp;sync.Pool{
          New: func() interface{} {
              return new(object)
          },
      }
  }
  
  var (
      lock     sync.RWMutex
      registry = make(map[string][]chan interface{})
  )
  
  func sub(topic string) chan interface{} {
      ch := make(chan interface{}, 10)
      lock.Lock()
      registry[topic] = append(registry[topic], ch)
      lock.Unlock()
      return ch
  }
  
  // publish goroutine
  func pub() {
      ticker := time.NewTicker(time.Second)
      o := pool.Get().(*object)
      o.info = &quot;new&quot;
      // do something
  
      for _ = range ticker.C {
          lock.RLock()
          for topic, chs := range registry {
              if o.info != &quot;new&quot; {
                  log.Printf(&quot;error&quot;)
              }
              if topic == &quot;hello&quot; {
                  for _, ch := range chs {
                      select {
                      case ch &lt;- o:
                      default:
                      }
                  }
              }
          }
          lock.RUnlock()
      }
  }
  
  func run(topic string) {
      ch := sub(topic)
      for {
          select {
          case o := &lt;-ch:
              switch o := o.(type) {
              case *object:
                  if o.info != &quot;new&quot; {
                      log.Printf(&quot;error&quot;)
                  }
  
                  // do something
                  time.Sleep(time.Second)
                  o.info = &quot;used&quot;
                  pool.Put(o)
              }
          }
      }
  }
  
  func main() {
      initPool()
  
      for i := 0; i &lt;= 100; i++ {
          go run(&quot;hello&quot;)
      }
      pub()
  }
  </code></pre>
  <p>The question is the object borrowed from pool can be accessed by multiple goroutines, so if one goroutine puts it back to the pool after using, it may be modified by other goroutines. I don't know when all goroutines are done with the object, so that I can put it back to pool.</p>