• 末班车
    2020-11-02
    之前用到去看过,好像是通过一个链表的形式,把request存起来,最新的在链表的头,最旧的在链表的尾部,可是不懂的是,为什么每次取出了req,还要重新赋零值呢,这和我每次new一个有什么区别么?求大佬指点。

    作者回复: 好问题。 重新赋零值相当于reset,避免先前的垃圾数据影响这个request。 new会在堆上新创建一个对象。

    共 3 条评论
    27
  • 那时刻
    2020-11-03
    请问老师, sync.Pool会有内存泄漏,怎么理解因为 Pool 回收的机制,这些大的 Buffer 可能不被回收?

    作者回复: 对

    共 6 条评论
    4
  • lesserror
    2021-08-21
    老师的文章讲解的非常细致。 请问一下: 1. 三色并发标记算法 这个 链接地址 Not found 了。 2. 举例大的buffer 不被回收的 第一个 源码 函数:putEncodeState ,我没找到。请问一下在哪个文件里面呀。

    作者回复: 第一个已修正,go官方网站域名改了。 第二个看文章的贴图

    
    1
  • 冰糕不冰
    2022-03-26
    讲的太好了! 真的是开启了新世界的大门。 感谢大佬

    作者回复: 谢谢点击[http://img01.sogoucdn.com/app/a/200678/64d6120c9ab37cb8ce7f52cea0ec9f75.gif]查看表情

    
    
  • tingting
    2022-01-24
    请问老师,RPC request 池化的实现为什么不用sync.Map,而是选择使用链表实现呢?

    作者回复: 链表更简单;map获取删除相对复杂;sync.pool会自动回收,不受控

    
    
  • 授人以🐟,不如授人...
    2021-11-04
    「因为 Pool 回收的机制,这些大的 Buffer 可能不被回收」是什么原因?

    作者回复: 因为每次是部分回收

    
    
  • Junes
    2020-11-02
    分享一下我的理解,主要分为回收和获取两个函数: 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 }
    展开
    共 1 条评论
    13
  • Yayu
    2020-11-03
    谢谢老师,喜欢老师这篇文章中通过外链的方式列出一些老师常用的三方库,很有用!
    
    8
  • 大布丁
    2022-03-20
    一文解决之前组长问我的一个问题:除了使用更多的goroutine来干更多的活之外,还有什么设计与优化的思想?当时没往线程池跟sync.Pool去思考,现在感触很深了!身为年轻人,代码功底不足的情况,我还是喜欢阅读源码后,动手实现里面的几个方法,以便于自己能够更深刻的去理解第三方库!
    
    1
  • 虫子樱桃
    2020-11-02
    思考题的奥秘感觉在这两个函数 ``` // 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() } ```
    展开
    共 2 条评论
    1