go version)?$ go version go version go1.14.2 linux/amd64
yes
go env)?go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/user"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/user/src/golang.org/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/user/src/golang.org/go/pkg/tool/linux_amd64"
GCCGO="/usr/bin/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-build845352725=/tmp/go-build -gno-record-gcc-switches"
$ cat <<EOF > a.go
package main
import (
"fmt"
)
type foo struct {
data [256 * 256 * 256 * 32]byte
}
func f() foo {
return foo{}
}
func main() {
x := f()
fmt.Println("%v", x.data[0])
}
EOF
$ go build a.go
https://play.golang.org/p/OZpuS_MxVNx
A binary file less than 2MB.
A binary file of ~514MiB size.
For what it's worth, gccgo produces a sane binary (38KiB, dynamic linking).
""..stmp_0 SRODATA size=536870912
""..stmp_2 SRODATA size=536870912
There are some really big static temps used to initialize instances of type foo. One at the return site of foo (which goes away because foo is inlined?) and one in main to initialize the heap-allocated foo (the compiler heap allocates x because it is too large).
We shouldn't be copying from zeroed data to initialize anything - we should just zero it directly.
An easier fix would be to allocated all-zero static temps in BSS, so at least they don't bloat the binary.
It seems that disabling this section of code can avoid the problem.
I have a fix in the works.
Change https://golang.org/cl/229704 mentions this issue: cmd/compile: optimize Move with all-zero ro sym src to Zero
Change https://golang.org/cl/229707 mentions this issue: cmd/compile: avoid double-zeroing
Most helpful comment
There are some really big static temps used to initialize instances of type
foo. One at the return site offoo(which goes away becausefoois inlined?) and one inmainto initialize the heap-allocatedfoo(the compiler heap allocatesxbecause it is too large).We shouldn't be copying from zeroed data to initialize anything - we should just zero it directly.
An easier fix would be to allocated all-zero static temps in BSS, so at least they don't bloat the binary.