-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Description
What version of Go are you using (go version
)?
$ go version go version go1.15.3 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="auto" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/go/pkg/mod" GONOPROXY="gitlab.corp.wabtec.com" GONOSUMDB="gitlab.corp.wabtec.com" GOOS="linux" GOPATH="/go" GOPRIVATE="gitlab.corp.wabtec.com" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/workspaces/rm-edge-hst/go.mod" 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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build132198306=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I reviewed the runtime source as I was looking for a stubborn memory leak in a long running process and discovered a code path that I think leaks memory. @josharian Encouraged me to raise an issue here after discussion on gophers slack #performance channel.
What did you expect to see?
No indefinite repeated calls to runtime.persistentalloc
in a long running process.
What did you see instead?
runtime.MemProfileRate int = 512 * 1024
by default i.e. > 0 (https://golang.org/src/runtime/mprof.go?h=MemProfileRate#L493)mallocgc
will therefore callprofilealloc
periodically due toMemProfileRate > 0
(https://golang.org/src/runtime/malloc.go?h=profilealloc#L1140)profilealloc
will callmProf_Malloc
(https://golang.org/src/runtime/malloc.go?h=mProf_Malloc#L1236)mProf_Malloc
will callstkbucket
(https://golang.org/src/runtime/mprof.go?h=stkbucket#L344)stkbucket
will callnewBucket
(https://golang.org/src/runtime/mprof.go?h=newBucket#L240)newBucket
will callpersistentalloc
withsize
equal tounsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0)) + unsafe.Sizeof(memRecord{})
(https://golang.org/src/runtime/mprof.go?h=persistentalloc#L173)
So, even if nstk == 0
the minimum persistent allocation would be unsafe.Sizeof(bucket{}) + unsafe.Sizeof(memRecord{})
which is 144 bytes (https://play.golang.org/p/5JCqMHh_2aO). If I have understood this correctly, this means that we are guaranteed to leak at least 144 bytes every MemProfileRate
by default.
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.