如何解决Go http标准库中的内存泄漏?
从pprof
您在注释中提供的堆中,看来您正在通过gorilla/sessions
和gorilla/context
(将近400MB)泄漏内存。
- 请参阅以下ML线程:[https](https://groups.google.com/forum/#!msg/gorilla-
- web/clJfCzenuWY/N_Xj9-5Lk6wJ) :
- [//groups.google.com/forum/#!](https://groups.google.com/forum/#!msg/gorilla-
- web/clJfCzenuWY/N_Xj9-5Lk6wJ) msg/gorilla-web/clJfCzenuWY/
- [N_Xj9-5Lk6wJ](https://groups.google.com/forum/#!msg/gorilla-
- web/clJfCzenuWY/N_Xj9-5Lk6wJ)和此GH问题:https
- //github.com/gorilla/sessions/issues/ 15
这是一个泄漏速度非常快的版本:
package main
import (
"fmt"
// "github.com/gorilla/context"
"github.com/gorilla/sessions"
"net/http"
)
var (
cookieStore = sessions.NewCookieStore([]byte("cookie-secret"))
)
func main() {
http.HandleFunc("/", defaultHandler)
http.ListenAndServe(":8080", nil)
}
func defaultHandler(w http.ResponseWriter, r *http.Request) {
cookieStore.Get(r, "leak-test")
fmt.Fprint(w, "Hi there")
}
package main
import (
"fmt"
"github.com/gorilla/context"
"github.com/gorilla/sessions"
"net/http"
)
var (
cookieStore = sessions.NewCookieStore([]byte("cookie-secret"))
)
func main() {
http.HandleFunc("/", defaultHandler)
http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
}
func defaultHandler(w http.ResponseWriter, r *http.Request) {
cookieStore.Get(r, "leak-test")
fmt.Fprint(w, "Hi there")
}
解决方法
让Go二进制程序实现http服务器:
package main
import (
"net/http"
)
func main() {
http.ListenAndServe(":8080",nil)
}
它将以大约850 kb的内存开始。通过网络浏览器发送一些请求。观察它很快上升到1 mb。如果您等待,您将看到它永远不会失败。现在,使用Apache
Bench对其进行锤打(使用下面的脚本),并查看您的内存使用量在不断增加。一段时间后,它将最终稳定在8.2 MB左右。
编辑:它似乎并没有在8.2处停止,而是明显放慢了速度。目前为9.2,并且仍在上升。
简而言之,为什么会这样?我使用了这个shell脚本:
while [ true ]
do
ab -n 1000 -c 100 http://127.0.0.1:8080/
sleep 1
end
在尝试深入了解这一点的同时,我尝试调整设置。我尝试关闭使用r.Close = true
以防止保持活动状态。似乎没有任何作用。
我最初是在尝试确定正在编写的程序中是否存在内存泄漏时才发现的。它有很多http处理程序和I /
O调用。检查完所有数据库连接后,我继续看到它的内存使用量增加。我的程序稳定在 433 MB 左右。
这是Goenv的输出:
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mark/Documents/Programming/Go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
TERM="dumb"
CC="clang"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fno-common"
CXX="clang++"
CGO_ENABLED="1"
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。