4.1 减小编译后的可执行文件体积
...大约 2 分钟
1. 直接编译
type Result struct {
Num, Ans int
}
type Calc int
// Square calculates the square of num
func (calc *Calc) Square(num int, result *Result) error {
result.Num = num
result.Ans = num * num
return nil
}
func main() {
rpc.Register(new(Calc))
rpc.HandleHTTP()
log.Printf("Serving RPC server on port %d", 1234)
if err := http.ListenAndServe(":1234", nil); err != nil {
log.Fatal("Error serving: ", err)
}
}
直接编译,大小约 9.2 MB:
$ go build .
dir | Select-Object Name, @{Name="MegaBytes";Expression={$_.Length / 1MB}}
Name MegaBytes
---- ---------
04-compile.exe 9.23876953125
1.1 编译选项
Golang 编译器直接编译的程序会带有符号表和调试信息,release 版本可以考虑去除调试信息以减小体积:
$ go build -ldflags '-s -w' .
$ dir | Select-Object Name, @{Name="MegaBytes";Expression={$_.Length / 1MB}}
Name MegaBytes
---- ------article: false
---
04-compile.exe 6.47216796875
-ldflags
:go tool link
选项-s
:忽略符号表和调试信息-w
:忽略DWARFv3调试信息,使用该选项后将无法使用gdb进行调试
约为 6.4 MB,体积减小了约 30%。
2. 使用工具 UPX
2.1 UPX
UPX is an advanced executable file compressor. UPX will typically reduce the file size of programs and DLLs by around 50%-70%, thus reducing disk space, network load times, download times and other distribution and storage costs.
upx 是一个常用的压缩动态库和可执行文件的工具,通常可减少 50-70% 的体积。
2.2 直接使用
upx 中参数最重要的是压缩率,取值范围[1,9]
其中1
为最低压缩率,9
为最高压缩率。
$ go build -o main_using_upx && upx -9 main_using_upx
9,687,552 main.exe
5,234,176 main_using_upx
体积约下降了 46%。
2.3 组合 upx 和 编译选项
$ go build -ldflags "-s -w" -o main_using_upx_ldflags && upx -9 main_using_upx_ldflags
5,234,176 main_using_upx
2,464,768 main_using_upx_ldflags
体积下降了约 52 %,直接编译大小为 9,687,552B
,使用UPX和编译选项之后约下降了 74%。
2.4 UPX 原理
upx 压缩后的程序和压缩前的程序一样,无需解压仍然能够正常地运行,这种压缩方法称之为带壳压缩,压缩包含两个部分:
- 在程序开头或其他合适的地方插入解压代码
- 将程序的其他部分压缩
执行时,也包含两个部分:
- 首先执行的是程序开头的插入的解压代码,将原来的程序在内存中解压出来
- 再执行解压后的程序
upx 在程序执行时,会有额外的解压动作,不过这个耗时几乎可以忽略。若对编译后的体积没什么要求的情况下,可以不使用 upx 来压缩。一般在服务器端独立运行的后台服务,无需压缩体积。
Reference
Powered by Waline v2.15.2