两年前,我的文章"为什么我的Go可执行文件如此之大?" 显示HOWTO使用D3和树图可视化以探索GO编译器生成的可扩展文件的大小。 Go工具NM报告的大小的总和不会加入到Go可执行文件的最终大小。 首先,我怀疑这个大小由符号表本身或调试信息占用。 要检查此功能,我们可以使用条带删除符号表并观察差异。 唉: 因此,仍然存在〜68mib的差距,或者未达到的〜34%的不合适数据。 此时,我没有对此“黑暗”文件使用情况的令人满意的解释。 我们可以看到这种黑暗文件用法在整个蟑螂的增长过程中如何发展: “剥离”是施加的条带命令后可执行的大小; 即,删除符号表和调试信息后。
“sum nm -size”是符号表的enteriess的广告大小的总和。
“Symtable SZ。”是符号表本身的估计大小,通过取向前两种尺寸之间的差异来置入。我们概念v1.0.7至v2.0.7可执行文件以及v20.1.0,预先剥离。
“暗字节”是原始文件大小与广告符号大小的组合和符号表的大小之间的差距,以字节为单位。
“%暗字节”是暗字节相对于Theraw文件大小的百分比。
我们可以看到暗尺寸百分比低于TocockroachdB V19.1之前的20%,然后在V21.1之前已经振荡大约33%的33%。随着即将到来的V21.1释放,使用Go 1.15,暗尺寸再次降至15%。
如前面的分析中所述,最高可达1.15的编译器将生成一个名为Runtime.pclntabinside的特殊表。
该数据结构的目的是使Go运行时系统能够通过Runtime.getStack API在崩溃或受到内部请求时生成描述性堆栈迹线。
我们可以看到此表在V1.13,v1.15中的v1.15降低至V1.15之前的转发版本 PCLNTAB的大尺寸是由于Go TeamTo将程序计数器的映射存储到未压缩的功能名称。 在1.2之前,Go Linker正在发出压缩线表,程序将在运行时初始化时将其解压缩。 在Go 1.2中,将执行文件预先扩展到其最终格式的决定,以在运行时适用于运行时使用,而无需额外的解压缩步骤。 换句话说,Go团队决定使可执行文件Largerto保存在初始化时间上。 正如我们所讨论的那样,对于很少执行的网络服务器LikeCockroachDB,此选择不充分保证,并且在磁盘上的磁盘上的大小超过启动时间。 我的文章在2019年出版,以及它触发的社区特征,实际上是由去团队注意到的。
从Go 1.16开始,PCLNTAB不再存在,而是从可执行文件中的其他数据重新计算。 究竟怎么了? 阅读。 使用蟑螂v21.1-alpha-geb1a69bc4的源代码,我们可以在Linux和FreeBSD上生成自定义构建,其中1.15和1.16编译器。 以前由PCLNTAB占用的字节现在是DarkBytes的一部分,它不在符号表中。 当然,去团队可以为“PCLNTAB已经减少到零”,但净效应对脱心尺寸的效果不是那么清晰可见! 思考上面的结果的有趣方式是,我们现在有三个部分无法真正协调的Go可执行文件,以便进行程序“工作”: 符号表本身(可以通过条带剥离,但默认情况下剥离)。 “暗字节”,它是符号表中的原始可执行文件中的字节用法。
仍然有多少个字节是“有用”的?我们可以计算如下: 删除黑暗尺寸(已占用的所有符号的负大小)。 为了总结,早期(在1.8和之前)的非码,可执行文件的非数据部分占总可执行大小的40%。 即使在Go 1.16中使用新的PCLNTAB替换,那么在运行时计算PCLNTAB,也没有增益:计算为计算的数据使用的数据存储在可执行文件中的某个位置,总体大小大于原始PCLNTAB也是如此。 版权所有©2021,Raphael'Kena'Pover。 根据Creative Commons atticution-Sharealike 4.0国际许可的条款,授予允许分发,重用和修改本文件。 原始文章可以在这里找到。 要查看本许可证的副本,请访问http://creativeCommons.org/licenses/by-sa/4.0/。