减小 Go 代码编译后的二进制体积

news2024/12/22 23:33:24

1 基线用例

减小编译后的二进制的体积,能够加快程序的发布和安装过程。接下来呢,我们分别从编译选项和第三方压缩工具两方面来介绍如何有效地减小 Go 语言编译后的体积。

我们采用同一个测试工程来测试不同方式的效果。

使用的测试工程如下,该程序启动了一个 RPC 服务,引用了 lognet/http 和 net/rpc 三个 package。

package main

import (
	"log"
	"net/http"
	"net/rpc"
)

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.8M。

$ go build -o server main.go
$ ls -lh server
-rwxr-xr-x  1 dj  staff   9.8M Dec  7 23:57 server

 

2 编译选项

Go 编译器默认编译出来的程序会带有符号表和调试信息,一般来说 release 版本可以去除调试信息以减小二进制体积。

$ go build -ldflags="-s -w" -o server main.go
$ ls -lh server
-rwxr-xr-x  1 dj  staff   7.8M Dec  8 00:29 server

 

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

体积从 9.8M 下降到 7.8M,下降约 20%。

3 使用 upx 减小体积

3.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% 的体积。

upx 的安装方式非常简单,我们可以直接从 github 下载最新的 release 版本,支持 Windows 和 Linux,在 Ubuntu 或 Mac 可以直接使用包管理工具安装。例如 Mac 下可以直接使用 brew:

$ brew install upx
$ upx
Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2020
UPX 3.96        Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 23rd 2020

Usage: upx [-123456789dlthVL] [-qvfk] [-o file] file..
...
Type 'upx --help' for more detailed help.

3.2 仅使用 upx

upx 有很多参数,最重要的则是压缩率,1-91 代表最低压缩率,9 代表最高压缩率。

接下来,我们看一下,如果只使用 upx 压缩,二进制的体积可以减小多少呢。

$ go build -o server main.go && upx -9 server
        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
  10253684 ->   5210128   50.81%   macho/amd64   server 
$ ls -lh server
-rwxr-xr-x  1 dj  staff   5.0M Dec  8 00:45 server

 

可以看到,使用 upx 后,可执行文件的体积从 9.8M 缩小到了 5M,缩小了 50%。

3.3 upx 和编译选项组合

$ go build -ldflags="-s -w" -o server main.go && upx -9 server
        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   8213876 ->   3170320   38.60%   macho/amd64   server 
$ ls -lh server
-rwxr-xr-x  1 dj  staff   3.0M Dec  8 00:47 server

 

使用编译选项后,体积从原来的 9.8M 下降了 20% 到 7.8M,使用 upx 压缩后,体积进一步下降 60% 到 3M。累进下降约 70%。

3.4 upx 的原理

upx 压缩后的程序和压缩前的程序一样,无需解压仍然能够正常地运行,这种压缩方法称之为带壳压缩,压缩包含两个部分:

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

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

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

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

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

laiyuan减小 Go 代码编译后的二进制体积 | Go 语言高性能编程 | 极客兔兔 Go 语言/golang 高性能编程,Go 语言进阶教程,Go 语言高性能编程(high performance go)。介绍了 2 种方式(编译选项和 UPX 工具) 来减小 Go 代码编译后的二进制文件/可执行文件的体积/大小。https://geektutu.com/post/hpg-reduce-size.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL全自动化检查神器

介绍 Yearning MYSQL 是一个SQL语句审核平台。提供查询审计,SQL审核等多种功能,支持Mysql,可以在一定程度上解决运维与开发之间的那一环,功能丰富,代码开源,安装部署容易! 功能介绍 SQL查询查询…

Prometheus配合 alertmanager 使用邮箱报警

部署Prometheus 和 Alertmanager略 安装包部署prometheusGrafananode_exporter_争取不加班!的博客-CSDN博客 prometheus监控报警部署Alertmanager_争取不加班!的博客-CSDN博客 编辑Alertmanager配置文件 vim alertmanager/alertmanager.yml global: res…

MySQL高可用之主备同步:MySQL是如何保证主备一致的

🏆今日学习目标: 🍀MySql是如何保证主备一致的 ✅创作者:林在闪闪发光 ⏰预计时间:30分钟 🎉个人主页:林在闪闪发光的个人主页 🍁林在闪闪发光的个人社区,欢迎你的加入:…

【Java编程进阶】封装继承多态详解

推荐学习专栏:Java 编程进阶之路【从入门到精通】 文章目录 1. 封装2. 继承2.1 继承的语法2.2 子类重写父类的方法2.3 子类隐藏父类的方法2.4 super 关键字2.5 final 关键字2.6 父类子类类型转换3. 多态4. 总结Java 是一门面向对象程序设计语言,其具有封装,继承和多态三大特…

面向对象的特征之三:多态性

文章目录一、理解多态性二、什么是多态性三、多态性的使用——虚拟方法调用四、多态性使用前提五、适用范围六、虚拟方法调用详细介绍多态性是编译期的还是运行期的?举例每日一考七、instanceof关键字的使用引入:关于多态性的讨论向下转型:in…

Linux-7 文本编辑vi/vim

Linux-7 文本编辑vi/vim vim介绍 什么是vim? vi和vim是Linux下的一个文本编辑工具。(可以李姐为Windows的记事本或word文档) 为什么要使用vim? 因为Linux系统一切皆为文件,而我们工作最多的就是修改某个服务的配置&a…

网络安全——投票系统缺陷(靶场实战)

我们需要利用漏洞来把投票信息刷到第一位 我们可以利用 HTTP_X_FORWARDED_FOR 来进行获取伪造 我们再次进行投票的时候,我们抓取数据包的格式 我们采用上述方法进行伪造 增加变量,我们采用多IP攻击 选中247点击send to Intruder 选中247和1点击 add&…

基于Xlinx的时序分析与约束(8)----关于时序路径、时钟悲观度和建立时间/保持时间的一些问题

写在前面 最近研究vivado里的时序分析路径时,发现了3个很有意思的问题。经过一番查找资料后,总算把问题搞明白了,在这里分享给大家。 1、为什么同一条时序路径在报表里的值不一样? 在如下文件建立的工程中: module te…

Window10下配置Maxim SDK

参考网址: 微信(中文):【嵌入式AI开发&Maxim篇一】美信Maxim78000Evaluation Kit AI部署流程初探 GitHub:MaximAI_Documentation/MAX78000_Feather at master MaximIntegratedAI/MaximAI_Documentation 下载地址…

【回答问题】ChatGPT上线了!如何安装python-ipopt?python-ipopt有哪些用法?

如何安装python-ipopt? 要安装 python-ipopt,你需要先安装 Ipopt 库。这个库是用 C 编写的,所以你还需要安装一些 C 编译器。 在 Linux 系统上,你可以使用下面的命令来安装 Ipopt 和相关的依赖项: 复制 sudo apt-g…

excel成本统计:如何进行区域筛选,多条件求和?

最近有位小伙伴被一个计算产品成本的问题难住了,要求是根据配件成本核算出成品的成本。这个问题看上去似乎有点复杂,感觉一下子想不出好的解决办法,实际上,却非常简单,而且仅用常见的求和函数,就能轻松解决…

Mybatis源码分析(四)Mapper文件的解析

目录一 Mapper的使用二 MapperElement的解析三 解析cache-ref节点四 解析Cache节点五 解析ParameterMap节点六 解析ResultMap节点七 解析Sql节点八 处理各个数据库操作语句官网:mybatis – MyBatis 3 | 简介 参考书籍:《通用源码阅读指导书:M…

【每日一题】【LeetCode】【第一天】三数之和

三数之和的解决之路 题干表述 测试案列(部分) 第一次思路 这种其实是最暴力的,也是我脑海里第一个想到的最简单的方法了。 思路就是三个循环,一个循环去一个数,然后当三个下标不同,且对应的三个数相加为…

FPGA设计CPU书籍

一直以来CPU内部是绝大多数IT工程师难以触及的领域。纵使学习过计算机架构相关课程,自己动手实现CPU也始终遥不可及,因为这涉及计算机系统的最底层——芯片设计。 而近年来FPGA芯片产品的发展与普及打破了这一阻碍,利用内部电路可重编程的FPG…

【C++进阶】IO流

🎇C学习历程:入门 博客主页:一起去看日落吗持续分享博主的C学习历程博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 也许你现在做的事情,暂时看不到成果,但不要忘记&…

Docker进阶(中)

docker 进阶(中)docker提交镜像等命令docker 镜像原理docker 私有库&推送到私有库容器数据卷docker 安装常规软件docker提交镜像等命令 再这个谈这个docker 提交这个镜像之前我们先补充一下上一篇博客没有谈到的命令。再这里说一下。我们之前谈到的…

代码随想录算法训练营第六天 java :242.有效的字母异位词 349. 两个数组的交集 ,1. 两数之和

文章目录哈希表理论基础哈希碰撞: 拉链法和线性探测法线性探测法Leetcode242.有效的字母异位词题目链接思路AC代码Leetcode349. 两个数组的交集题目链接思路AC代码Leetcode 1. 两数之和题目链接思路与难点AC代码收获今日收获哈希表理论基础 哈希函数如下图所示&…

【C++】string (上)(string类的常用接口 string类对象的容量操作 string类对象的访问及遍历操作 string类对象的修改操作)

文章目录string标准库中的string类string类的常用接口string类对象的容量操作string类对象的访问及遍历操作string类对象的修改操作string string是一个专门管理字符数组的类。 标准库中的string类 string是表示字符串的字符串类该类的接口与常规容器的接口基本相同&#xff0…

计算机二级python考前复习笔记

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言程序设计风格:清晰第一,效率第二。结构化程序设计原则:自顶向下,逐步求精,模块化,限制使用goto语句(Python无 goto 语句&#xf…

【回答问题】ChatGPT上线了!SLAM有哪些模型实现代码/案例/github源码?推荐10个以上比较好的SLAM深度学习模型?

目录SLAM有哪些模型实现代码?SLAM有哪些模型实现案例?SLAM有哪些模型的github源码?推荐10个以上比较好的SLAM深度学习模型?推荐10个以上比较好的SLAM深度学习模型github源码?SLAM有哪些模型实现代码? SLAM…