我认为以下代码正在大量泄漏。分析它我怀疑defer r.Close()
从未被调用过。
在这里有更好的方法可以使用Reader和gzip吗?
// Read client data from channel
func (c *Client) listen() {
timeoutDuration := 30 * time.Second
reader := bufio.NewReader(c.conn)
clientBuffer := new(bytes.Buffer)
for {
c.conn.SetReadDeadline(time.Now().Add(timeoutDuration))
byte, err := reader.ReadByte()
if err != nil {
c.conn.Close()
c.server.onClientConnectionClosed(c, err)
return
}
clientBuffer.WriteByte(byte)
packet := popPacketFromBuffer(clientBuffer)
if packet != nil {
packetBuffer := bytes.NewBuffer(packet)
r, _ := gzip.NewReader(packetBuffer)
defer r.Close()
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
c.server.onNewMessage(c, b)
}
}
}
答案 0 :(得分:3)
您的问题是defer
函数仅在函数结束时调用。不是循环。所以,是的,他们很可能保持开放。
一种方法是将紧密循环封装到函数中。
func uncompress(packet []byte) ([]byte, error) {
r, _ := gzip.NewReader(bytes.NewBuffer(packet))
defer r.Close()
return ioutil.ReadAll(r)
}
// Read client data from channel
func (c *Client) listen() {
/* … */
for {
/* … */
if packet != nil {
b, err := uncompress(packet)
if err != nil {
log.Fatal(err)
}
c.server.onNewMessage(c, b)
}
}
}
另一种方法是展开延迟电话并手动完成。
// Read client data from channel
func (c *Client) listen() {
/* … */
for {
/* … */
if packet != nil {
r, _ := gzip.NewReader(bytes.NewBuffer(packet))
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
r.Close()
c.server.onNewMessage(c, b)
}
}
}