缩小golang编译后的可执行文件体积

起因

今天在Ubuntu下使用go build编译项目的时候,忽然发现编译后的可执行文件有22M,项目资源并不多呀?这个体积是正常的吗?

以前一直没有注意这个情况,心血来潮去Google搜索了一下,忽然发现了新大陆,原来可以压缩体积很多,体积少点总归是有好处,分发的时候传输页方便。

这里特意记录一下我的尝试。

尝试使用编译参数

按查询的资料所说,golang默认编译的时候,会把符号表和调试信息一起打包进可执行文件中。

这些信息能让你在程序问题的时候,快速定位问题,并解决问题。

正常的编译命令是:

1
$ go build -o server

编译后文件的体积是:

1
-rwxrwxr-x  1 lzm lzm  22M 2月   3 16:03 server*

去除符号表编译:

1
$ go build -o server -ldflags="-s -w"

编译后文件的体积是:

1
-rwxrwxr-x  1 lzm lzm  16M 2月   3 16:05 server*

可以看到体积减少了8M,下降了36%

编译参数的含义

  • -s: 忽略符号表和调试信息
  • -w: 忽略DWARFv3调试信息,使用了该选项后无法使用gdb进行调试

可以看到,加上了这两个参数,体积是减少了,但是调试也不方便了,服务端程序对体积不敏感的情况下,建议不要加上这两个参数。

使用upx工具

upx是一个压缩动态库和可执行文件的工具,通常可以减少50%-70%的体积。 支持windows,Mac,linux。我的开发机是ubuntu, 直接使用apt-get安装。

1
$ sudo apt-get install upx

安装好以后,直接使用。

1
2
3
4
5
6
7
$ go build -o server| upx -9 server
        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
  22663989 ->  11407128   50.33%   linux/amd64   server

$ ll -h
-rwxrwxr-x  1 lzm lzm  11M 2月   3 16:14 server*

可以看到,在只使用upx的情况下,压缩了11M50%的压缩率。

我们编译时候去除符号表和调试信息后,再次使用upx压缩。

1
2
3
4
5
6
7
$ go build -o server -ldflags="-s -w" | upx -9 server
        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
  16322560 ->   5989056   36.69%   linux/amd64   server

$ ll -h
-rwxrwxr-x  1 lzm lzm 5.8M 2月   3 16:17 server*

可以看出,体积压缩了10M,压缩率达到了63%

upx命令有很多个参数,最重要的是1-9表示压缩级别,1表示最低,9表示最高。

upx压缩后的程序不影响原程序的运行结果,也不需要解压缩运行,这种压缩叫带壳压缩。

具体upx的原理大家自行搜索。

0%