Skip to content

go/parser,go/types: memory usage doubled in 1.17 #49035

@danmillwood

Description

@danmillwood

What version of Go are you using (go version)?

$ go version
go version go1.17.2 linux/amd64

Does this issue reproduce with the latest release?

Yes (assuming 1.17.2 is latest release

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.2"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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-build2626739605=/tmp/go-build -gno-record-gcc-switches"

What did you do?

The Kubernetes open source code includes a verification step that performs cross compile validation for a number of target systems. Im not familiar with the code but the README states that it does the following:

Typecheck does cross-platform typechecking of source code for all Go build
platforms.

The primary benefit is speed: a full Kubernetes cross-build takes 20 minutes
and >40GB of RAM, while this takes under 2 minutes and <8GB of RAM.

It uses Go's built-in parsing and typechecking libraries (go/parser and
go/types)

https://github.com/kubernetes/kubernetes/blob/master/test/typecheck/README

With go 1.16 and below, these checks could be run on a system with 8GB RAM. With go 1.17.2 this now requires more than double the amount of RAM to avoid out of memory issues. It appears something in go 1.17 is using significantly more memory.

The shell script to run the check is here https://github.com/kubernetes/kubernetes/blob/master/hack/verify-typecheck.sh

Recreating the OOM can be done by pulling down the Kubernetes open source package from https://github.com/kubernetes/kubernetes and running hack/verify-typecheck.sh with a go 1.17.2 compiler on a Linux VM with 8GB memory.

What did you expect to see?

I modified hack/lib/golang.sh to set minimum_go_version=go1.16.0 and ran the test with go 1.16.9. The result was

root@kubernetes1804:~/go/src/k8s.io/kubernetes# hack/verify-typecheck.sh
type-checking windows/arm64
type-checking windows/386
ERROR(windows/arm64): failed to verify: err: exit status 2: stderr: cmd/go: unsupported GOOS/GOARCH pair windows/arm64

type-checking darwin/amd64
type-checking linux/amd64
type-checking linux/386
type-checking linux/arm
type-checking windows/amd64
type-checking linux/arm64
type-checking linux/ppc64le
type-checking linux/s390x
type-checking darwin/arm64
exit status 1

What did you see instead?

With go 1.17.2 I get

root@kubernetes1804:~/go/src/k8s.io/kubernetes# hack/verify-typecheck.sh
Generating prerelease lifecycle code for 6 targets
Generating deepcopy code for 36 targets
Generating defaulter code for 13 targets
Generating conversion code for 19 targets
Generating openapi code for KUBE
Generating openapi code for AGGREGATOR
Generating openapi code for APIEXTENSIONS
Generating openapi code for CODEGEN
Generating openapi code for SAMPLEAPISERVER
type-checking windows/arm64
type-checking linux/arm
fatal error: runtime: out of memory

runtime stack:
runtime.throw({0x6205fa, 0x800000})
	/usr/local/go/src/runtime/panic.go:1198 +0x71
runtime.sysMap(0xc2c5800000, 0x428c40, 0xc1688bbe90)
	/usr/local/go/src/runtime/mem_linux.go:169 +0x96
runtime.(*mheap).grow(0x7bb680, 0x242)
	/usr/local/go/src/runtime/mheap.go:1393 +0x225
runtime.(*mheap).allocSpan(0x7bb680, 0x242, 0x0, 0x0)
	/usr/local/go/src/runtime/mheap.go:1179 +0x165
runtime.(*mheap).alloc.func1()
	/usr/local/go/src/runtime/mheap.go:913 +0x69
runtime.systemstack()
	/usr/local/go/src/runtime/asm_amd64.s:383 +0x49


Id like to be able to let the kubernetes community know whether this is a performance change that can be fixed, or whether folks verifying a kubernetes build will need significantly more memory.

Metadata

Metadata

Assignees

Labels

FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions