Go 语言编译器编译出来的二进制文件体积通常比较大,尤其是使用了第三方库的情况下。因此减小编译后的二进制文件体积,有助于加快程序的发布和安装速度。接下来,我们将从编译选项优化和使用第三方压缩工具两个方面,介绍在 Go 语言中如何有效地缩减生成文件的大小。
如下我们有一个简单的 Go 语言程序,使用了 gin 框架。
package main
import "github.com/gin-gonic/gin"
func main() {
// 启动gin
r := gin.Default()
// 启动服务
r.Run(":8080")
}
使用默认选项编译该程序,编译后的程序大小约为 12M。
$ ls -alh server
-rwxr-xr-x 1 wong 197121 12M Apr 16 18:16 server*
Go 编译器默认编译的二进制文件包含了调试信息和符号表等信息,这些信息在调试时非常有用,但在发布时并不需要。我们可以使用 -ldflags
选项来去掉这些信息。
$ go build -ldflags="-s -w" -o server
$ ls -alh server
-rwxr-xr-x 1 wong 197121 8.0M Apr 16 18:18 server*
体积从 12M 下降到 8M,下降约 33%。
upx 是一个常用的压缩动态库和可执行文件的工具,通常可减少 50-70% 的体积。
upx 的安装方式非常简单,我们可以直接从 github 下载最新的 release 版本,支持 Windows 和 Linux,在 Linux 或 Mac 可以直接使用包管理工具安装。例如:
# Ubunntu
$ sudo apt-get install upx
# Fedora/CentOS/RHEL
$ sudo yum install upx
# Mac
$ brew install upx
upx 有很多参数,最重要的则是压缩率,1-9
,1
代表最低压缩率,9
代表最高压缩率。
接下来我们使用 upx 来压缩编译后的二进制文件。
$ go build -o server && upx -9 server
$ ls -alh server
-rwxr-xr-x 1 wong 197121 6.0M Apr 16 18:31 server*
可以看到,使用 upx 后,可执行文件的体积从 12M 缩小到了 6M,缩小了 50%。
$ go build -ldflags="-s -w" -o server && upx -9 server
$ ls -alh server
-rwxr-xr-x 1 wong 197121 2.7M Apr 16 18:32 server*
使用编译选项后,体积从原来的 12M 下降了 20% 到 8M,使用 upx 压缩后,体积进一步下降 66% 到 2.7M。累进下降约 77%。
upx
的原理upx
压缩后的程序和压缩前的程序一样,无需解压仍然能够正常地运行,这种压缩方法称之为带壳压缩,压缩包含两个部分:
执行时,也包含两个部分:
也就是说,upx
在程序执行时,会有额外的解压动作,不过这个耗时几乎可以忽略。
如果对编译后的体积没什么要求的情况下,可以不使用 upx
来压缩。一般在服务器端独立运行的后台服务,无需压缩体积。