关于 Go 的编译及体积优化

简介: 关于 Go 的编译及体积优化

编译方式

静态编译

在Go中,可以使用静态编译来将Go程序编译为一个独立的可执行文件,其中包含了所有的依赖库和运行时环境,不需要依赖外部的共享库。这样就可以在没有Go语言环境的机器上直接运行编译后的可执行文件。

# output-file 是输出的可执行文件名
go build -o output-file main.go

优点是可以将这个可执行文件复制到其他机器上,无需安装Go语言环境,就可以直接运行它。

缺点是生成的可执行二进制文件的体积较大。

动态编译

Go语言本身不支持动态编译(即在运行时动态加载和执行代码)。

但是 Go 1.8及以上版本引入了插件机制,允许在运行时动态加载和执行插件代码。

可以将插件代码编译为插件模块,然后在主程序中通过插件机制加载和执行该模块。使用plugin包可以实现这个功能。

另外,可以使用Go语言的外部库来实现动态加载和执行其他语言的代码。

例如,使用cgo库可以与C语言进行交互,通过加载和执行C代码来实现动态编译的效果。也可以使用与其他语言的交互库,如go-python、go-lua等,来加载和执行相应语言的代码。

减少静态编译后的二进制体积

1. 指定编译参数

# -s 去掉符号信息
# -w 去掉调试信息
go build -ldflags="-s -w" -o output-file main.go

实测可以原本的 33M 可以减少到 27M。

2. 压缩

UPX https://github.com/upx/upx 是一个可执行文件的压缩工具。

UPX压缩包含两个部分:

  • 在程序开头或其他合适的地方插入解压代码;
  • 将程序的其他部分压缩。

程序执行时,也包含两个部分:

  • 首先执行的是程序开头的插入的解压代码,将原来的程序在内存中解压出来;
  • 再执行解压后的程序。

也就是说,upx 在程序执行时,会有额外的解压动作,不过这个耗时几乎可以忽略。

如果对编译后的体积没什么要求的情况下,可以不使用 upx 来压缩。一般在服务器端独立运行的后台服务,无需压缩体积。

# 安装UPX
wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-amd64_linux.tar.xz
tar -Jxf upx*.tar.xz
sudo cp upx*/upx /usr/bin
upx -v
# 压缩
upx [options] yourfile

-1[23456789]:不同的压缩级别,数值越高压缩率越高,但耗时更长。
对于小于 512 KiB 的文件默认使用 -8,其他的默认为 -7。
    --best:最高压缩级别
    --brute:尝试使用各种压缩方式来获取最高压缩比
    --ultra-brute:尝试使用更多的参数来获取更高的压缩比

-o [file]:将压缩文件保存为 [file]

优点

  • UPX 可以压缩各种类型的可执行文件

  • 压缩后的文件可以直接由操作系统执行

  • 压缩过程不会修改源文件,也就意味着解压后直接可以得到原始文件

  • 不会产生额外的动态库调用

缺点

  • 运行的程序不会共享数据段(汇编),所以多实例运行的程序不适合压缩
  • 使用 ldd 和 size 命令无法获取到程序的有效信息
# 具体使用
go build -ldflags="-s -w" -o output-file main.go && upx output-file

实测可以将 33M 减少到 7.1M 。

UPX 参考

目录
相关文章
|
编译器 测试技术 Go
Go语言的自给自足:编译自身的神奇之旅
Go语言的自给自足:编译自身的神奇之旅
|
3月前
|
监控 Java 编译器
限流、控并发、减GC!一文搞懂Go项目资源优化的正确姿势
本章介绍Go语言项目在构建与部署阶段的性能调优和资源控制策略,涵盖编译优化、程序性能提升、并发与系统资源管理、容器化部署及自动化测试等内容,助力开发者打造高效稳定的生产级应用。
|
3月前
|
存储 安全 算法
Go语言泛型-泛型对代码结构的优化
Go语言自1.18版本引入泛型,极大提升了代码的通用性与可维护性。通过泛型,开发者可以减少重复代码、提高类型安全性,并增强程序的复用性和可读性。本文详细介绍了泛型在数据结构、算法及映射功能中的应用,展示了其在优化代码结构方面的优势。同时,Go编译器对泛型代码进行类型推导,确保运行时性能不受影响。合理使用泛型,有助于构建更加灵活高效的程序。
|
5月前
|
机器学习/深度学习 存储 监控
上网管理监控软件的 Go 语言流量特征识别算法实现与优化
本文探讨基于Go语言的流量特征识别算法,用于上网管理监控软件。核心内容涵盖AC自动机算法原理、实现及优化,通过路径压缩、哈希表存储和节点合并策略提升性能。实验表明,优化后算法内存占用降低30%,匹配速度提升20%。在1000Mbps流量下,CPU利用率低于10%,内存占用约50MB,检测准确率达99.8%。未来可进一步优化高速网络处理能力和融合机器学习技术。
151 10
|
10月前
|
监控 Java Go
编译时插桩,Go应用监控的最佳选择
本文讲解了阿里云编译器团队和可观测团队为了实现Go应用监控选择编译时插桩的原因,同时还介绍了其他的监控方案以及它们的优缺点。
908 113
|
11月前
|
存储 负载均衡 监控
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
223 1
|
11月前
|
编译器 Go
go语言编译选项
【10月更文挑战第17天】
213 5
|
11月前
|
Go
go语言编译时常量表达式
【10月更文挑战第20天】
116 3
|
11月前
|
Go
go语言使用常量和编译时常量表达式
【10月更文挑战第19天】
129 2
|
10月前
|
Go 数据安全/隐私保护 UED
优化Go语言中的网络连接:设置代理超时参数
优化Go语言中的网络连接:设置代理超时参数