go语言共享内存池 go语言内存管理( 四 )


Put过程:
如何解决Get最坏情况遍历所有P才获取得对象呢:
方法1止前sync.pool并没有这样的设置 。方法2由于goroutine被分配到哪个P由调度器调度不可控 , 无法确保其平衡 。
由于不可控的GC导致生命周期过短 , 且池大小不可控,因而不适合作连接池 。仅适用于增加对象重用机率,减少GC负担 。2
执行结果:
单线程情况下,遍历其它无元素的P , 长时间加锁性能低下 。启用协程改善 。
结果:
测试场景在goroutines远大于GOMAXPROCS情况下,与非池化性能差异巨大 。
测试结果
可以看到同样使用*sync.pool , 较大池大小的命中率较高 , 性能远高于空池 。
结论:pool在一定的使用条件下提高并发性能,条件1是协程数远大于GOMAXPROCS,条件2是池中对象远大于GOMAXPROCS 。归结成一个原因就是使对象在各个P中均匀分布 。
池pool和缓存cache的区别 。池的意思是,池内对象是可以互换的,不关心具体值,甚至不需要区分是新建的还是从池中拿出的 。缓存指的是KV映射 , 缓存里的值互不相同,清除机制更为复杂 。缓存清除算法如LRU、LIRS缓存算法 。
池空间回收的几种方式 。一些是GC前回收,一些是基于时钟或弱引用回收 。最终确定在GC时回收Pool内对象,即不回避GC 。用java的GC解释弱引用 。GC的四种引用:强引用、弱引用、软引用、虚引用 。虚引用即没有引用 , 弱引用GC但有空间则保留,软引用GC即清除 。ThreadLocal的值为弱引用的例子 。
regexp 包为了保证并发时使用同一个正则 , 而维护了一组状态机 。
fmt包做字串拼接,从sync.pool拿[]byte对象 。避免频繁构建再GC效率高很多 。
go语言共享内存池的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言内存管理、go语言共享内存池的信息别忘了在本站进行查找喔 。

推荐阅读