Go: cmd/compile: significant binary size increase in go1.11

Created on 27 Aug 2018  Â·  22Comments  Â·  Source: golang/go

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

 âš¡ root@k8s î‚° /home/ubuntu î‚° go version
go version go1.11 linux/amd64

Does this issue reproduce with the latest release?

Yep, upgrade the golang to version 1.11 and build the software.

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

 âš¡ root@k8s î‚° /home/ubuntu î‚° go env
GOARCH="amd64"
GOBIN="/usr/local/go/bin"
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/paasdata/gopath"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build147710718=/tmp/go-build -gno-record-gcc-switches"

What did you do?

  1. For example, let's build hyperkube (kubernetes v1.11.1) with go1.10.3
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° go version
go version go1.10.3 linux/amd64
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° make hyperkube
+++ [0827 14:21:57] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/deepcopy-gen
+++ [0827 14:22:08] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/defaulter-gen
+++ [0827 14:22:16] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/conversion-gen
+++ [0827 14:22:24] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/openapi-gen
+++ [0827 14:22:35] Building go targets for linux/amd64:
    ./vendor/github.com/jteeuwen/go-bindata/go-bindata
+++ [0827 14:22:37] Building go targets for linux/amd64:
    cmd/hyperkube
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°
  1. Check the generated binary files, the hyperkube is 217M
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° ll -h _output/local/bin/linux/amd64
total 255M
-rwxr-xr-x 1 root root 7.4M Aug 27 14:22 conversion-gen
-rwxr-xr-x 1 root root 7.4M Aug 27 14:21 deepcopy-gen
-rwxr-xr-x 1 root root 7.4M Aug 27 14:22 defaulter-gen
-rwxr-xr-x 1 root root 2.8M Aug 27 14:22 go-bindata
-rwxr-xr-x 1 root root 217M Aug 27 14:26 hyperkube
-rwxr-xr-x 1 root root  14M Aug 27 14:22 openapi-gen
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°
  1. Change the golang to 1.11, build hyperkube (kubernetes v1.11.1) again
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° make clean
+++ [0827 14:33:26] Verifying Prerequisites....
+++ [0827 14:33:26] Removing _output directory
Removing pkg/generated/openapi/zz_generated.openapi.go ..
Removing test/e2e/generated/bindata.go ..
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° rm -rf /usr/local/go
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° ln -s /usr/local/go1.10.3 /usr/local/go
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° go version
go version go1.10.3 linux/amd64
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° go version
go version go1.11 linux/amd64
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° make hyperkube
+++ [0827 14:33:53] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/deepcopy-gen
+++ [0827 14:34:05] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/defaulter-gen
+++ [0827 14:34:12] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/conversion-gen
+++ [0827 14:34:21] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/openapi-gen
+++ [0827 14:34:32] Building go targets for linux/amd64:
    ./vendor/github.com/jteeuwen/go-bindata/go-bindata
+++ [0827 14:34:34] Building go targets for linux/amd64:
    cmd/hyperkube
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°
  1. Check the new files, the hyperkube increased to 275M, the size increased 26.7% compared to versions 1.10.3
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° ll -h _output/local/bin/linux/amd64
total 313M
-rwxr-xr-x 1 root root 7.4M Aug 27 14:34 conversion-gen
-rwxr-xr-x 1 root root 7.4M Aug 27 14:33 deepcopy-gen
-rwxr-xr-x 1 root root 7.3M Aug 27 14:34 defaulter-gen
-rwxr-xr-x 1 root root 2.7M Aug 27 14:34 go-bindata
-rwxr-xr-x 1 root root 275M Aug 27 14:37 hyperkube
-rwxr-xr-x 1 root root  13M Aug 27 14:34 openapi-gen
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°

What did you expect to see?

The compiler version upgrade has little effect on the size of the generated binary.

What did you see instead?

The size increased 26.7% compared to 1.10.x versions.

NeedsInvestigation binary-size

Most helpful comment

I compiled a hello world go app the other day and noticed the binary had functions for cuneiform. While five thousand years of backwards compatibility is commendable, I'd expected that its linker be capable of exercising greater parsimony.

All 22 comments

And go1.11 consumes more resources, there are some issue (https://github.com/golang/go/issues/26186 & https://github.com/golang/go/issues/26132 ) tracker this.

Use go1.10.3 to compile normally, but switching to go1.11 will give an error.

 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° free -h
              total        used        free      shared  buff/cache   available
Mem:           7.6G        966M        5.8G        5.7M        922M        6.4G
Swap:          1.0G        444M        579M
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° make all
+++ [0827 14:50:27] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/deepcopy-gen
+++ [0827 14:50:37] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/defaulter-gen
+++ [0827 14:50:44] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/conversion-gen
+++ [0827 14:50:53] Building go targets for linux/amd64:
    ./vendor/k8s.io/code-generator/cmd/openapi-gen
+++ [0827 14:51:03] Building go targets for linux/amd64:
    ./vendor/github.com/jteeuwen/go-bindata/go-bindata
+++ [0827 14:51:05] Building go targets for linux/amd64:
    cmd/kube-proxy
    cmd/kube-apiserver
    cmd/kube-controller-manager
    cmd/cloud-controller-manager
    cmd/kubelet
    cmd/kubeadm
    cmd/hyperkube
    cmd/kube-scheduler
    vendor/k8s.io/kube-aggregator
    vendor/k8s.io/apiextensions-apiserver
    cluster/gce/gci/mounter
    cmd/kubectl
    cmd/gendocs
    cmd/genkubedocs
    cmd/genman
    cmd/genyaml
    cmd/genswaggertypedocs
    cmd/linkcheck
    vendor/github.com/onsi/ginkgo/ginkgo
    test/e2e/e2e.test
    cmd/kubemark
    vendor/github.com/onsi/ginkgo/ginkgo
    test/e2e_node/e2e_node.test
/usr/local/go/pkg/tool/linux_amd64/link: signal: killed
# k8s.io/kubernetes/cmd/hyperkube
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: signal: killed

!!! [0827 14:56:34] Call tree:
!!! [0827 14:56:34]  1: /paasdata/gopath/src/k8s.io/kubernetes-1.11.1/hack/lib/golang.sh:610 kube::golang::build_binaries_for_platform(...)
!!! [0827 14:56:34]  2: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
!!! [0827 14:56:34] Call tree:
!!! [0827 14:56:34]  1: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
!!! [0827 14:56:34] Call tree:
!!! [0827 14:56:34]  1: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
make: *** [all] Error 1
 ✘ ⚡ root@k8s  /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 

There's an umbrella bug for binary size: #6853. I'm going to leave this one open now, though, to make sure we understand this specific regression. In particular, is it due to DWARF size increases (#26074)? Can you run sizecmp on your binaries? Thanks.

Hi @josharian the sizecmp dependon otool, which is the tools for OSX, and can't run on my linux env:

 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° ./sizecmp hyperkube-go1.11 hyperkube-go1.10.3
2018/08/28 10:21:39 otool -l hyperkube-go1.11: exec: "otool": executable file not found in $PATH

Use bloaty to analyse the binaries:

The size increase is not just DWARF information, I rebuild the file with flag GOLDFLAGS="-s -w" (trip DWARF, debuginfo, symbol).

As shown in the following data, the size increased about 16%.

 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° ll -h ./hyperkube-go1.1*-w
-rwxr-xr-x 1 root root 132M Aug 28 10:38 ./hyperkube-go1.10.3-s-w
-rwxr-xr-x 1 root root 153M Aug 28 10:32 ./hyperkube-go1.11-s-w
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°

Our internal project also compiled with -s -w: (The debug binaries are a tad bit smaller in 1.11 tan those from 1.10, but that's due to DWARF compression) 1.11 also ~14% larger images

  • 1.10 13.607.104 bytes
  • 1.11 15.875.680 bytes

From https://github.com/golang/go/issues/27784#issuecomment-423351536:

"bloaty suggests the extra size is coming from __gopclntab"

The bloaty analyse result by "make all WHAT=cmd/hyperkube":

 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° bloaty ./hyperkube-go1.10.3
     VM SIZE                       FILE SIZE
 --------------                 --------------
  41.0%  53.9Mi .text            53.9Mi  24.8%
   0.0%       0 .debug_info      41.3Mi  19.1%
  30.5%  40.1Mi .rodata          40.1Mi  18.5%
  25.5%  33.5Mi .gopclntab       33.5Mi  15.4%
   0.0%       0 .strtab          15.1Mi   7.0%
   0.0%       0 .debug_pubtypes  8.65Mi   4.0%
   0.0%       0 .debug_frame     6.26Mi   2.9%
   0.0%       0 .debug_line      4.95Mi   2.3%
   0.0%       0 .symtab          4.29Mi   2.0%
   2.6%  3.40Mi .noptrdata       3.40Mi   1.6%
   0.0%       0 .debug_pubnames  2.99Mi   1.4%
   0.0%       0 .debug_ranges    1.92Mi   0.9%
   0.2%   253Ki .typelink         253Ki   0.1%
   0.1%   186Ki .bss                  0   0.0%
   0.1%   139Ki .data             139Ki   0.1%
   0.0%  47.2Ki .itablink        47.2Ki   0.0%
   0.0%  16.4Ki [31 Others]      22.5Ki   0.0%
   0.0%       0 .debug_loc       19.0Ki   0.0%
   0.0%  17.5Ki .noptrbss             0   0.0%
   0.0%       0 .debug_abbrev    9.21Ki   0.0%
   0.0%       0 .debug_str       6.61Ki   0.0%
 100.0%   131Mi TOTAL             216Mi 100.0%
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° bloaty ./hyperkube-go1.11
     VM SIZE                       FILE SIZE
 --------------                 --------------
  35.8%  54.6Mi .text            54.6Mi  19.9%
  30.8%  47.0Mi .gopclntab       47.0Mi  17.1%
  30.7%  46.9Mi .rodata          46.9Mi  17.1%
   0.0%       0 .debug_info      42.3Mi  15.4%
   0.0%       0 .debug_loc       25.7Mi   9.4%
   0.0%       0 .strtab          15.1Mi   5.5%
   0.0%       0 .debug_line      8.95Mi   3.3%
   0.0%       0 .debug_pubtypes  8.47Mi   3.1%
   0.0%       0 .debug_ranges    8.19Mi   3.0%
   0.0%       0 .debug_frame     6.30Mi   2.3%
   0.0%       0 .symtab          4.31Mi   1.6%
   2.2%  3.40Mi .noptrdata       3.40Mi   1.2%
   0.0%       0 .debug_pubnames  3.04Mi   1.1%
   0.2%   251Ki .typelink         251Ki   0.1%
   0.1%   186Ki .bss                  0   0.0%
   0.1%   139Ki .data             139Ki   0.0%
   0.0%  47.2Ki .itablink        47.2Ki   0.0%
   0.0%  16.4Ki [31 Others]      22.3Ki   0.0%
   0.0%  17.9Ki .noptrbss             0   0.0%
   0.0%       0 .debug_abbrev    9.13Ki   0.0%
   0.0%       0 .debug_str       6.63Ki   0.0%
 100.0%   152Mi TOTAL             274Mi 100.0%
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°

The bloaty analyse result by 'make all WHAT=cmd/hyperkube GOLDFLAGS="-s -w"' (trip DWARF, debuginfo, symbol):

 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° bloaty ./hyperkube-go1.10.3-s-w
     VM SIZE                     FILE SIZE
 --------------               --------------
  41.0%  53.9Mi .text          53.9Mi  41.0%
  30.5%  40.1Mi .rodata        40.1Mi  30.5%
  25.5%  33.5Mi .gopclntab     33.5Mi  25.5%
   2.6%  3.40Mi .noptrdata     3.40Mi   2.6%
   0.2%   253Ki .typelink       253Ki   0.2%
   0.1%   186Ki .bss                0   0.0%
   0.1%   139Ki .data           139Ki   0.1%
   0.0%  47.2Ki .itablink      47.2Ki   0.0%
   0.0%  17.5Ki .noptrbss           0   0.0%
   0.0%  3.91Ki .dynsym        3.91Ki   0.0%
   0.0%  3.57Ki .eh_frame      3.57Ki   0.0%
   0.0%  3.05Ki .dynstr        3.05Ki   0.0%
   0.0%     624 [ELF Headers]  2.80Ki   0.0%
   0.0%     866 [18 Others]    1.26Ki   0.0%
   0.0%  1.12Ki .rela.plt      1.12Ki   0.0%
   0.0%     988 .gnu.hash         988   0.0%
   0.0%       0 [Unmapped]        983   0.0%
   0.0%     784 .plt              784   0.0%
   0.0%     700 .eh_frame_hdr     700   0.0%
   0.0%     496 .dynamic          496   0.0%
   0.0%     408 .got.plt          408   0.0%
 100.0%   131Mi TOTAL           131Mi 100.0%
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚° bloaty ./hyperkube-go1.11-s-w
     VM SIZE                     FILE SIZE
 --------------               --------------
  35.8%  54.6Mi .text          54.6Mi  35.8%
  30.8%  47.0Mi .gopclntab     47.0Mi  30.8%
  30.7%  46.9Mi .rodata        46.9Mi  30.8%
   2.2%  3.40Mi .noptrdata     3.40Mi   2.2%
   0.2%   251Ki .typelink       251Ki   0.2%
   0.1%   186Ki .bss                0   0.0%
   0.1%   139Ki .data           139Ki   0.1%
   0.0%  47.2Ki .itablink      47.2Ki   0.0%
   0.0%  17.9Ki .noptrbss           0   0.0%
   0.0%  3.91Ki .dynsym        3.91Ki   0.0%
   0.0%  3.57Ki .eh_frame      3.57Ki   0.0%
   0.0%  3.05Ki .dynstr        3.05Ki   0.0%
   0.0%     624 [ELF Headers]  2.80Ki   0.0%
   0.0%     875 [18 Others]    1.27Ki   0.0%
   0.0%  1.12Ki .rela.plt      1.12Ki   0.0%
   0.0%     988 .gnu.hash         988   0.0%
   0.0%     784 .plt              784   0.0%
   0.0%       0 [Unmapped]        767   0.0%
   0.0%     700 .eh_frame_hdr     700   0.0%
   0.0%     496 .dynamic          496   0.0%
   0.0%     408 .got.plt          408   0.0%
 100.0%   152Mi TOTAL           152Mi 100.0%
 âš¡ root@k8s î‚° /paasdata/gopath/src/k8s.io/kubernetes-1.11.1 î‚°

I'll also kindly rope in some more folks who might be interested in this bug @randall77 @ianlancetaylor @bradfitz @cherrymui @heschik

/cc @dr2chase @aclements

I haven't looked into this deeply at all, but growth in .gopclntab would seem to implicate https://golang.org/issue/24543 (safepoints everywhere). The design doc there says to expect growth of ~10% unless optimizations are applied.

The growth in .gopclntab is almost certainly mostly from safepoints everywhere, but that's only 13.5MB of growth, or 6.25% of overall growth in the unstripped binary and 10% growth in the stripped binary.

Here's a section-by-section comparison from benchstat of the bloaty output:

For unstripped binaries:

name             old MB     new MB     delta
.debug_pubtypes  8.65 ± 0%  8.47 ± 0%    -2.08%
.noptrdata       3.40 ± 0%  3.40 ± 0%    +0.00%
.strtab          15.1 ± 0%  15.1 ± 0%    +0.00%
.symtab          4.29 ± 0%  4.31 ± 0%    +0.47%
.debug_frame     6.26 ± 0%  6.30 ± 0%    +0.64%
.text            53.9 ± 0%  54.6 ± 0%    +1.30%
.debug_pubnames  2.99 ± 0%  3.04 ± 0%    +1.67%
.debug_info      41.3 ± 0%  42.3 ± 0%    +2.42%
.rodata          40.1 ± 0%  46.9 ± 0%   +16.96%
TOTAL             216 ± 0%   274 ± 0%   +26.85%
.gopclntab       33.5 ± 0%  47.0 ± 0%   +40.30%
.debug_line      4.95 ± 0%  8.95 ± 0%   +80.81%
.debug_ranges    1.92 ± 0%  8.19 ± 0%  +326.56%

For .gopclntab, it would be reasonable to strip the safepoints everywhere data in -dwarf=off mode. That's only used for debugger call injection right now, which isn't much use without DWARF data.

1.12 once again increases binary size on the 1.11.

1.11

  • stripped 13262208
  • nonstripped 17759088

1.12 beta1

  • stripped 13872672
  • nonstripped 18950335

~600k increase on stripped binary. :/ and ~1,2M on nonstripped one

Let's keep comments here objective. Obviously nobody likes unnecessarily large binaries but having everybody declare what their subjective tolerances are for different applications isn't incredibly helpful and is just distracting.

If there's something specific about our generated wasm that's making this problem worse than other platforms then that'd be interesting.

I compiled a hello world go app the other day and noticed the binary had functions for cuneiform. While five thousand years of backwards compatibility is commendable, I'd expected that its linker be capable of exercising greater parsimony.

@jart, the compiler & linker do a lot in that area, but it often stops being great once it sees an interface value. It does little to no proving to itself what concrete types of values can go in interfaces. There are several open bugs in that area, but they're all tricky.

If you want to file new bugs with concrete examples (after searching for existing dups), that'd be helpful. This bug is more of a meta bug.

@jart, in particular, the bug you're seeing is https://github.com/golang/go/issues/2559

Found this with a binary of mine that includes a more complicated set of parsers:

$ bloaty polyglot-go1.11.5 
     VM SIZE                              FILE SIZE
 --------------                        --------------
  61.5%  26.7Mi __TEXT,__text           26.7Mi  48.5%
   0.0%       0 [Unmapped]              11.9Mi  21.5%
  26.4%  11.4Mi __TEXT,__gopclntab      11.4Mi  20.8%
   8.6%  3.72Mi __TEXT,__rodata         3.72Mi   6.7%
   1.9%   823Ki String Table             823Ki   1.5%
   0.8%   338Ki Symbol Table             338Ki   0.6%
   0.4%   179Ki __DATA,__noptrdata       179Ki   0.3%
   0.3%   126Ki __DATA,__bss                 0   0.0%
   0.1%  58.5Ki __DATA,__data           58.5Ki   0.1%
   0.0%  13.7Ki __TEXT,__typelink       13.7Ki   0.0%
   0.0%  12.5Ki __DATA,__noptrbss            0   0.0%
   0.0%  3.24Ki __TEXT,__itablink       3.24Ki   0.0%
   0.0%  2.50Ki [Mach-O Headers]        2.60Ki   0.0%
   0.0%  2.48Ki [__TEXT]                2.38Ki   0.0%
   0.0%     688 __DATA,__nl_symbol_ptr     688   0.0%
   0.0%     676 Indirect Symbol Table      676   0.0%
   0.0%     498 __TEXT,__symbol_stub1      498   0.0%
   0.0%      79 [__DATA]                    63   0.0%
 100.0%  43.4Mi TOTAL                   55.1Mi 100.0%

$ bloaty polyglot-go1.12beta2 
     VM SIZE                              FILE SIZE
 --------------                        --------------
  59.3%  26.7Mi __TEXT,__text           26.7Mi  45.8%
   0.0%       0 [Unmapped]              13.5Mi  23.1%
  26.7%  12.0Mi __TEXT,__gopclntab      12.0Mi  20.6%
   9.5%  4.28Mi __TEXT,__rodata         4.28Mi   7.3%
   2.6%  1.19Mi String Table            1.19Mi   2.0%
   1.0%   455Ki Symbol Table             455Ki   0.8%
   0.4%   179Ki __DATA,__noptrdata       179Ki   0.3%
   0.3%   122Ki __DATA,__bss                 0   0.0%
   0.1%  58.8Ki __DATA,__data           58.8Ki   0.1%
   0.0%  14.0Ki __TEXT,__typelink       14.0Ki   0.0%
   0.0%  12.6Ki __DATA,__noptrbss            0   0.0%
   0.0%  5.06Ki [__TEXT]                4.96Ki   0.0%
   0.0%  3.37Ki __TEXT,__itablink       3.37Ki   0.0%
   0.0%  2.50Ki [Mach-O Headers]        2.60Ki   0.0%
   0.0%  1.02Ki __DATA,__nl_symbol_ptr  1.02Ki   0.0%
   0.0%  1.00Ki Indirect Symbol Table   1.00Ki   0.0%
   0.0%     756 __TEXT,__symbol_stub1      756   0.0%
   0.0%      71 [__DATA]                    55   0.0%
 100.0%  45.1Mi TOTAL                   58.4Mi 100.0%

A 3 MB increase.

I see that rodata is growing in many of these reports. I wonder where that is coming from as well.

FYI, there is a new discussion of gopclntab in #36313

/label binary-size

This bug seems pretty non-actionable (we already have a meta bug, linked above, and a bunch of specific bugs). It doesn't help to have another meta bug open.

I suspected the Go 1.15 improvements (stack maps, register maps, linker, etc) fixed this anyway, so I went to measure on a big program. Kubernetes is too ugly to build (I wanted something that just used Go modules & worked back to Go 1.11) so took @Xe's program above (https://github.com/golang/go/issues/27266#issuecomment-458686871) and removed a couple lines from it to make it build. I get:

-rwxr-xr-x 1 bradfitz bradfitz 65780209 May  2 08:43 bin.go1.11
-rwxr-xr-x 1 bradfitz bradfitz 69293793 May  2 08:52 bin.go1.12
-rwxr-xr-x 1 bradfitz bradfitz 64294920 May  2 08:34 bin.go1.14
-rwxr-xr-x 1 bradfitz bradfitz 61902583 May  2 08:32 bin.go1.15

I didn't measure Go 1.10 because it doesn't support Go modules and I couldn't be bothered to fight a GOPATH. But let's assume Go 1.10 was a bit smaller than Go 1.11.

Go 1.12 was certainly worse than Go 1.11, but Go 1.14 got better than Go 1.11, and then Go 1.15(-dev) is the best yet. Maybe it's even down to Go 1.10 size. If somebody has a self-contained large program that builds in all versions, let us know.

In any case, I'm going to close this bug as fixed, at least enough.

The plenty of others bugs labeled binary-size track more specific improvements we could make.

Was this page helpful?
0 / 5 - 0 ratings