-
Notifications
You must be signed in to change notification settings - Fork 18.5k
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 * 1024by default i.e. > 0 (https://golang.org/src/runtime/mprof.go?h=MemProfileRate#L493)mallocgcwill therefore callprofileallocperiodically due toMemProfileRate > 0(https://golang.org/src/runtime/malloc.go?h=profilealloc#L1140)profileallocwill callmProf_Malloc(https://golang.org/src/runtime/malloc.go?h=mProf_Malloc#L1236)mProf_Mallocwill callstkbucket(https://golang.org/src/runtime/mprof.go?h=stkbucket#L344)stkbucketwill callnewBucket(https://golang.org/src/runtime/mprof.go?h=newBucket#L240)newBucketwill callpersistentallocwithsizeequal 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.