-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
net/http: memory leak due to a large number of items in transport.reqCanceler
What version of Go are you using (go version
)?
$ go version go version go1.19.10 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="on" GOARCH="amd64" GOBIN="/home/xxx/codes/go/bin" GOCACHE="/home/xxx/.cache/go-build" GOENV="/home/xxx/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/xxx/codes/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/xxx/codes/go" GOPRIVATE="" GOPROXY="https://goproxy.cn,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.19.10" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/xxx/codes/transport-memory-leak/go.mod" GOWORK="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3608446700=/tmp/go-build -gno-record-gcc-switches"
What did you do?
When using http.ReverseProxy to build http ReverseProxy, We found memory leak in http.Transport in certain case.
There is a client , proxy and server as bellow, :
client -----> proxy -----> server
reproduce condition:
- client concurrently visit proxy(maybe 200+ concurrency).
- server receive request head and return response immediately(server response before receive entired request body).
proxy code:
https://go.dev/play/p/dRzdohisHy5?v=goprev
server code:
https://go.dev/play/p/iyBuNbJWKVi?v=goprev
client code:
https://go.dev/play/p/7gPDzt9vrkw?v=goprev
What did you expect to see?
http.ReverseProxy perform well and has no memory leak.
What did you see instead?
proxy error logs:
2023/08/02 10:37:52 httputil: ReverseProxy read error during body copy: read tcp 127.0.0.1:53946->127.0.0.1:9090: use of closed network connection
PProf file shows that memory leak in transport:
dlv debug info shows the memory leak is caused by reqCanceler. 1900+ items in the reqCanceller map should be gc after we stop client, but after a long time, they are still there.
a sample request(proxy -> server) diagram of tcpdump.
Source code and some files for further debug:
transport-memory-leak.zip