Skip to content

cmd/compile: compiling nested generics consumes a lot of memory and takes a long time #76661

Description

@Daniil159x

Go version

go version go1.25.4 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build447586909=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/app/go.mod'
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'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.4'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Hi!
I found the module github.com/barweiss/go-tuple and I was trying to create a named tuple (like in python, or a dictionary or something like a struct).
I also tried adding chain methods to create a named tuple, similar to how zerolog creates a log object:

a := ZeroMap0{}.
		Int("a", 11).
		Int("b", 22323343)

The chaining methods return the following generic structure with an additional generic parameter.
Thus, a generic of level N creates a generic of level N+1 - hence the name nested generics.

See the full code: https://go.dev/play/p/uCYMGcXhqrZ

What did you see happen?

The compiling consumed 5.5 GB of RAM (resident aka rss) and lasted for 1.5 minutes.
I've captured the following graphs:
Memory:
Image

Flamegraph (click for original svg file):
Image

When limiting the nesting to 2-3 levels or just removing unused chain methods (.Str and .Any), compilation is completed instantly and does not require much RAM.
Flamegraph of compiling of generics of the first 2 levels only (the full code and original svg file):
Image

If, on the opposite, the nesting level is increased, then either the compilation does not complete, or it is killed by OOM.

The problem seems to be related to the reader.obj() method from src/cmd/compile/internal/noder/reader.go.
It is recursively called for each level and creates many temporary objects (however, this may be a false path, I have not profiled the allocation and don't know how to do this without building the compiler).

What did you expect to see?

Fast compilation without consuming gigabytes of memory.

Metadata

Metadata

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status
Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions