Closed warmchang closed 4 years ago
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
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
1.12 beta1
~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.
What version of Go are you using (
go version
)?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
)?What did you do?
For example, let's build hyperkube (kubernetes v1.11.1) with go1.10.3
Check the generated binary files, the hyperkube is 217M
Change the golang to 1.11, build hyperkube (kubernetes v1.11.1) again
Check the new files, the hyperkube increased to 275M, the size increased 26.7% compared to versions 1.10.3
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.