you are better than you think

关于golang sync.Pool

· by thur · Read in about 1 min · (62 Words)
golang 临时对象池 sync.Pool

golang 官方为了解决对象重用问题提供了临时对象池:https://golang.org/src/sync/pool.go

对象池,是指提供了对象复用功能。临时是指对象池的没有引用的对象在每两分钟一次的GC中会被全部清理掉。有点坳口,下面我们来看一段代码。

package main

import (
    "log"
    "runtime"
    "sync"
)

func main() {
    p := &sync.Pool{
        New: func() interface{} {
            return 0
        },
    }
    a := p.Get().(int)
    p.Put(1)
    b := p.Get().(int)
    log.Println(a, b)
    p.Put(3)
    p.Put(4)
    p.Put(5)
    log.Println(p.Get()) //返回 3 4 5中的任意一个。
    //主动调用GC  pool中对象会被清理掉
    runtime.GC()
    p.Put(2)
    c := p.Get().(int)
    log.Println(c)
}

  总结下这个临时对象池的特点:

  1. 池不可以指定大小,大小只受制于GC临界值;
  2. 对象的最大缓存周期是GC 周期,当GC 调用时 没有被引用的对象都会被清理掉;
  3. Get方法返回时是返回池中任意一个对象,没有顺序;如果池中没有对象,那么调用New方法新生成一个;如果没有指定New方法,那么返回nil;

这个pool是官方为了解决对象复用提供的方案,当然在goroutine不多的情况下使用chan 来缓存对象也可以,当goroutine多了以后,那么对chan的竞争会影响整体性能。

这么好的东西是不是可以用来实现连接池减少短连接开销呢? 答案是不能。通过上面的总结也可以看出,临时对象池的对象适合于状态无关的对象,而长连接要判断连接状态。那么哪些场景适合使用这个pool呢?

Comments