Golang:许多goroutines的内存消耗

时间:2015-08-03 13:39:42

标签: memory go goroutine

我已经建立了一个用Go编写的http服务器,每天有超过数千名访问者。我有一个累积的Goroutine问题(从未被释放)。在一天的过程中,我似乎从http服务器上获得了一万多个新的Goroutines。我使用pprof来检查问题的来源,我得到了:

Link: memory consumption: SVG pprof

enter image description here

堆:

enter image description here

下面是我的两个goroutines

500 @ 0x410255 0x5a9255 0x5a9e25 0x5aa615 0x5990cf 0x5ada95 0x59d23f 0x4367b1
#   0x5a9255    net._C2func_getaddrinfo+0x55    /usr/local/go/src/net/:26
#   0x5a9e25    net.cgoLookupIPCNAME+0x1c5  /usr/local/go/src/net/cgo_unix.go:96
#   0x5aa615    net.cgoLookupIP+0x65        /usr/local/go/src/net/cgo_unix.go:148
#   0x5990cf    net.lookupIP+0x5f       /usr/local/go/src/net/lookup_unix.go:64
#   0x5ada95    net.func·026+0x55       /usr/local/go/src/net/lookup.go:79
#   0x59d23f    net.(*singleflight).doCall+0x2f /usr/local/go/src/net/singleflight.go:91

157871 @ 0x423985 0x4239f8 0x411464 0x410c93 0x5a9d68 0x5aa615 0x5990cf 0x5ada95 0x59d23f 0x4367b1
#   0x5a9d68    net.cgoLookupIPCNAME+0x108  /usr/local/go/src/net/cgo_unix.go:85
#   0x5aa615    net.cgoLookupIP+0x65        /usr/local/go/src/net/cgo_unix.go:148
#   0x5990cf    net.lookupIP+0x5f       /usr/local/go/src/net/lookup_unix.go:64
#   0x5ada95    net.func·026+0x55       /usr/local/go/src/net/lookup.go:79
#   0x59d23f    net.(*singleflight).doCall+0x2f /usr/local/go/src/net/singleflight.go:91

在这里,我们可以看到 singleflight.go 占用了大部分goroutints,它是Go的本地库。

我的代码在这个函数中被包围了

func getXmlVast(url string) (string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return "", errors.New("request error A(" + err.Error() + ")")
    }
    defer resp.Body.Close()
    // read xml http response
    xmlData, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", errors.New("request error B(" + err.Error() + ")")
    }
    return string(xmlData), nil
}

为什么Go永远不会释放goroutines以及 singleflight.go 做什么。

1 个答案:

答案 0 :(得分:0)

我将Go版本从1.4更新为1.5,它解决了问题。

我之前做了一些研究以找到问题的来源我注意到很多人都有同样的问题,没有人知道为什么。我认为这个问题出现在http/net库中因为我说的在我的问题中,充分利用goroutints的函数是单步,这个函数由http.Get(url)调用