10 | Pool:性能提升大杀器
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Go语言中的sync.Pool是一个性能提升的重要工具,通过对象池的方式回收不再使用的对象,避免重新创建,从而避免了垃圾回收对性能的影响。在Go 1.13中,sync.Pool经过优化,避免了使用锁,提高了性能。除了sync.Pool,文章还介绍了buffer池的使用场景和实现原理。同时,文章还提到了使用sync.Pool的注意事项,以及其它类型的Pool,如TCP连接池、数据库连接池等。此外,文章还介绍了Worker Pool的应用场景,帮助读者全方位地掌握标准库的Pool。总之,sync.Pool是一个强大的工具,能够有效提升Go语言程序的性能。文章还介绍了一些第三方库提供的buffer池和连接池,以及它们的特点和适用场景。另外,文章还提到了在分布式系统或者微服务框架中,可能会有大量的并发Client请求,如果Client的耗时占比很大,可以考虑池化Client,以便重用。如果系统中的goroutine数量非常多,程序的内存资源占用比较大,而且整体系统的耗时和GC也比较高,可以通过Worker Pool解决大量goroutine的问题,从而降低这些指标。
《Go 并发编程实战课》,新⼈⾸单¥59
全部留言(16)
- 最新
- 精选
- 末班车之前用到去看过,好像是通过一个链表的形式,把request存起来,最新的在链表的头,最旧的在链表的尾部,可是不懂的是,为什么每次取出了req,还要重新赋零值呢,这和我每次new一个有什么区别么?求大佬指点。
作者回复: 好问题。 重新赋零值相当于reset,避免先前的垃圾数据影响这个request。 new会在堆上新创建一个对象。
2020-11-02327 - 那时刻请问老师, sync.Pool会有内存泄漏,怎么理解因为 Pool 回收的机制,这些大的 Buffer 可能不被回收?
作者回复: 对
2020-11-0364 - lesserror老师的文章讲解的非常细致。 请问一下: 1. 三色并发标记算法 这个 链接地址 Not found 了。 2. 举例大的buffer 不被回收的 第一个 源码 函数:putEncodeState ,我没找到。请问一下在哪个文件里面呀。
作者回复: 第一个已修正,go官方网站域名改了。 第二个看文章的贴图
2021-08-211 - 冰糕不冰讲的太好了! 真的是开启了新世界的大门。 感谢大佬
作者回复: 谢谢点击[http://img01.sogoucdn.com/app/a/200678/64d6120c9ab37cb8ce7f52cea0ec9f75.gif]查看表情
2022-03-26 - tingting请问老师,RPC request 池化的实现为什么不用sync.Map,而是选择使用链表实现呢?
作者回复: 链表更简单;map获取删除相对复杂;sync.pool会自动回收,不受控
2022-01-24 - 授人以🐟,不如授人以渔「因为 Pool 回收的机制,这些大的 Buffer 可能不被回收」是什么原因?
作者回复: 因为每次是部分回收
2021-11-04 - Junes分享一下我的理解,主要分为回收和获取两个函数: func (server *Server) freeRequest(req *Request) { server.reqLock.Lock() // 将req放在freeReq的头部,指向原先的链表头 // 至于为什么放在头部、而不是尾部,我觉得是放在尾部需要遍历完这个链表(增加时间复杂度)、或者要额外维护一个尾部Request的指针(增加空间复杂度),权衡下放在头部更方便 req.next = server.freeReq server.freeReq = req server.reqLock.Unlock() } func (server *Server) getRequest() *Request { server.reqLock.Lock() // freeReq是一个链表,保存空闲的Request req := server.freeReq if req == nil { // 初始状态:freeReq为空时,在heap上重新分配一个对象 req = new(Request) } else { server.freeReq = req.next // 复用的关键在这里,这里并不是新建一个对象 new(Request) // 这里的思想类似于Reset,将原先有数据的Request设置为空 *req = Request{} } server.reqLock.Unlock() return req }2020-11-02113
- Yayu谢谢老师,喜欢老师这篇文章中通过外链的方式列出一些老师常用的三方库,很有用!2020-11-038
- 大布丁一文解决之前组长问我的一个问题:除了使用更多的goroutine来干更多的活之外,还有什么设计与优化的思想?当时没往线程池跟sync.Pool去思考,现在感触很深了!身为年轻人,代码功底不足的情况,我还是喜欢阅读源码后,动手实现里面的几个方法,以便于自己能够更深刻的去理解第三方库!2022-03-201
- 虫子樱桃思考题的奥秘感觉在这两个函数 ``` // ServeRequest is like ServeCodec but synchronously serves a single request. // It does not close the codec upon completion. func (server *Server) ServeRequest(codec ServerCodec) error { sending := new(sync.Mutex) service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) if err != nil { if !keepReading { return err } // send a response if we actually managed to read a header. if req != nil { server.sendResponse(sending, req, invalidRequest, codec, err.Error()) server.freeRequest(req) } return err } service.call(server, sending, nil, mtype, req, argv, replyv, codec) return nil } func (server *Server) freeRequest(req *Request) { server.reqLock.Lock() req.next = server.freeReq server.freeReq = req server.reqLock.Unlock() } ```2020-11-0221