- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
跟进How do I check the size of a Go project?
结论是:
in order to get a true sense of how much extra weight importing certain packages, one has to look at all of the pkg's sub-dependencies as well.
这完全可以理解。我的问题是,
我是否可以知道每个组件在我编译的二进制文件、Go 运行时、依赖项和子依赖项包以及我自己的代码中占用了多少空间。
我依稀记得以前读过类似的东西(可能是在 go 增强它的链接器的时候)。
如果以前从未有过这样的讨论,那么 go 甚至 c 链接器是否可以通过任何方式查看我编译的二进制文件,并揭示一些我可以自己进一步解析的东西?
最佳答案
二进制文件将包含调试符号,我们可以使用这些符号来计算每个包占用了多少空间。
我编写了一个基本程序来执行此操作,因为我不知道有任何工具可以执行此操作:
package main
import (
"debug/elf"
"fmt"
"os"
"runtime"
"sort"
"strings"
"github.com/go-delve/delve/pkg/proc"
)
func main() {
// Use delve to decode the DWARF section
binInfo := proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH)
err := binInfo.AddImage(os.Args[1], 0)
if err != nil {
panic(err)
}
// Make a list of unique packages
pkgs := make([]string, 0, len(binInfo.PackageMap))
for _, fullPkgs := range binInfo.PackageMap {
for _, fullPkg := range fullPkgs {
exists := false
for _, pkg := range pkgs {
if fullPkg == pkg {
exists = true
break
}
}
if !exists {
pkgs = append(pkgs, fullPkg)
}
}
}
// Sort them for a nice output
sort.Strings(pkgs)
// Parse the ELF file ourselfs
elfFile, err := elf.Open(os.Args[1])
if err != nil {
panic(err)
}
// Get the symbol table
symbols, err := elfFile.Symbols()
if err != nil {
panic(err)
}
usage := make(map[string]map[string]int)
for _, sym := range symbols {
if sym.Section == elf.SHN_UNDEF || sym.Section >= elf.SectionIndex(len(elfFile.Sections)) {
continue
}
sectionName := elfFile.Sections[sym.Section].Name
symPkg := ""
for _, pkg := range pkgs {
if strings.HasPrefix(sym.Name, pkg) {
symPkg = pkg
break
}
}
// Symbol doesn't belong to a known package
if symPkg == "" {
continue
}
pkgStats := usage[symPkg]
if pkgStats == nil {
pkgStats = make(map[string]int)
}
pkgStats[sectionName] += int(sym.Size)
usage[symPkg] = pkgStats
}
for _, pkg := range pkgs {
sections, exists := usage[pkg]
if !exists {
continue
}
fmt.Printf("%s:\n", pkg)
for section, size := range sections {
fmt.Printf("%15s: %8d bytes\n", section, size)
}
fmt.Println()
}
}
现在实际使用的空间分为多个部分(.text 用于代码,.bss 用于零初始化数据,.data 用于全局变量,等等)。此示例列出了每个部分的大小,但如果您愿意,您可以修改代码以获取总数。
这是它从自己的二进制文件生成的输出:
bufio:
.text: 12733 bytes
.noptrdata: 64 bytes
.bss: 176 bytes
.rodata: 72 bytes
bytes:
.bss: 48 bytes
.rodata: 64 bytes
.text: 12617 bytes
.noptrdata: 320 bytes
compress/flate:
.text: 20385 bytes
.noptrdata: 248 bytes
.bss: 2112 bytes
.noptrbss: 12 bytes
.rodata: 48 bytes
compress/zlib:
.text: 4138 bytes
.noptrdata: 96 bytes
.bss: 48 bytes
container/list:
.text: 4016 bytes
context:
.text: 387 bytes
.noptrdata: 72 bytes
.bss: 40 bytes
crypto:
.text: 20982 bytes
.noptrdata: 416 bytes
.bss: 96 bytes
.rodata: 58 bytes
.noptrbss: 3 bytes
debug/dwarf:
.rodata: 1088 bytes
.text: 113878 bytes
.noptrdata: 247 bytes
.bss: 64 bytes
debug/elf:
.rodata: 168 bytes
.text: 36557 bytes
.noptrdata: 112 bytes
.data: 5160 bytes
.bss: 16 bytes
debug/macho:
.text: 22980 bytes
.noptrdata: 96 bytes
.data: 456 bytes
.rodata: 80 bytes
debug/pe:
.text: 26004 bytes
.noptrdata: 96 bytes
.rodata: 288 bytes
encoding/base64:
.bss: 32 bytes
.rodata: 48 bytes
.text: 846 bytes
.noptrdata: 56 bytes
encoding/binary:
.text: 27108 bytes
.noptrdata: 72 bytes
.bss: 56 bytes
.rodata: 136 bytes
encoding/hex:
.bss: 16 bytes
.text: 288 bytes
.noptrdata: 64 bytes
encoding/json:
.rodata: 108 bytes
.text: 2930 bytes
.noptrdata: 128 bytes
.bss: 80 bytes
errors:
.rodata: 48 bytes
.text: 744 bytes
.noptrdata: 40 bytes
.bss: 16 bytes
fmt:
.text: 72010 bytes
.noptrdata: 136 bytes
.data: 104 bytes
.bss: 32 bytes
.rodata: 720 bytes
github.com/cilium/ebpf:
.text: 170860 bytes
.noptrdata: 1405 bytes
.bss: 608 bytes
.rodata: 3971 bytes
.data: 16 bytes
.noptrbss: 8 bytes
github.com/go-delve/delve/pkg/dwarf/frame:
.text: 18304 bytes
.noptrdata: 80 bytes
.bss: 8 bytes
.rodata: 211 bytes
github.com/go-delve/delve/pkg/dwarf/godwarf:
.text: 40431 bytes
.noptrdata: 144 bytes
.rodata: 352 bytes
github.com/go-delve/delve/pkg/dwarf/line:
.bss: 48 bytes
.rodata: 160 bytes
.text: 24069 bytes
.noptrdata: 96 bytes
github.com/go-delve/delve/pkg/dwarf/loclist:
.noptrdata: 64 bytes
.rodata: 64 bytes
.text: 4538 bytes
github.com/go-delve/delve/pkg/dwarf/op:
.text: 31142 bytes
.noptrdata: 80 bytes
.bss: 72 bytes
.rodata: 5313 bytes
github.com/go-delve/delve/pkg/dwarf/reader:
.noptrdata: 72 bytes
.bss: 16 bytes
.rodata: 24 bytes
.text: 8037 bytes
github.com/go-delve/delve/pkg/dwarf/regnum:
.bss: 40 bytes
.rodata: 2760 bytes
.text: 3943 bytes
.noptrdata: 48 bytes
github.com/go-delve/delve/pkg/dwarf/util:
.text: 4028 bytes
.noptrdata: 64 bytes
.rodata: 96 bytes
github.com/go-delve/delve/pkg/elfwriter:
.text: 3394 bytes
.noptrdata: 48 bytes
.rodata: 48 bytes
github.com/go-delve/delve/pkg/goversion:
.noptrdata: 104 bytes
.bss: 64 bytes
.rodata: 160 bytes
.text: 4415 bytes
github.com/go-delve/delve/pkg/logflags:
.bss: 32 bytes
.rodata: 40 bytes
.text: 2610 bytes
.noptrdata: 136 bytes
.noptrbss: 3 bytes
github.com/go-delve/delve/pkg/proc:
.text: 432477 bytes
.noptrdata: 718 bytes
.data: 1448 bytes
.bss: 592 bytes
.rodata: 10106 bytes
github.com/go-delve/delve/pkg/version:
.text: 1509 bytes
.noptrdata: 72 bytes
.data: 112 bytes
.rodata: 40 bytes
github.com/hashicorp/golang-lru/simplelru:
.text: 3911 bytes
.noptrdata: 32 bytes
.rodata: 160 bytes
github.com/sirupsen/logrus:
.noptrbss: 20 bytes
.rodata: 696 bytes
.text: 40175 bytes
.noptrdata: 204 bytes
.data: 64 bytes
.bss: 56 bytes
go/ast:
.text: 24407 bytes
.noptrdata: 104 bytes
.data: 112 bytes
.rodata: 120 bytes
go/constant:
.bss: 8 bytes
.rodata: 824 bytes
.text: 33910 bytes
.noptrdata: 88 bytes
go/parser:
.rodata: 1808 bytes
.text: 78751 bytes
.noptrdata: 136 bytes
.bss: 32 bytes
go/printer:
.text: 77202 bytes
.noptrdata: 113 bytes
.data: 24 bytes
.rodata: 1504 bytes
go/scanner:
.rodata: 240 bytes
.text: 18594 bytes
.noptrdata: 93 bytes
.data: 24 bytes
go/token:
.noptrdata: 72 bytes
.data: 1376 bytes
.bss: 8 bytes
.rodata: 192 bytes
.text: 7154 bytes
golang.org/x/arch/arm64/arm64asm:
.rodata: 856 bytes
.text: 116428 bytes
.noptrdata: 80 bytes
.bss: 80 bytes
.data: 46128 bytes
golang.org/x/arch/x86/x86asm:
.noptrdata: 29125 bytes
.bss: 112 bytes
.data: 20928 bytes
.rodata: 1252 bytes
.text: 76721 bytes
golang.org/x/sys/unix:
.text: 1800 bytes
.noptrdata: 128 bytes
.rodata: 70 bytes
.data: 80 bytes
hash/adler32:
.text: 1013 bytes
.noptrdata: 40 bytes
internal/bytealg:
.rodata: 56 bytes
.noptrbss: 8 bytes
.text: 1462 bytes
.noptrdata: 32 bytes
internal/cpu:
.rodata: 500 bytes
.noptrbss: 416 bytes
.noptrdata: 8 bytes
.bss: 24 bytes
.text: 3017 bytes
internal/fmtsort:
.text: 7443 bytes
.noptrdata: 40 bytes
.rodata: 40 bytes
internal/oserror:
.text: 500 bytes
.noptrdata: 40 bytes
.bss: 80 bytes
internal/poll:
.text: 31565 bytes
.rodata: 192 bytes
.noptrdata: 112 bytes
.data: 96 bytes
.bss: 64 bytes
.noptrbss: 12 bytes
internal/reflectlite:
.text: 13761 bytes
.noptrdata: 32 bytes
.data: 456 bytes
.bss: 24 bytes
.rodata: 496 bytes
internal/syscall/unix:
.rodata: 72 bytes
.text: 708 bytes
.noptrdata: 40 bytes
.noptrbss: 4 bytes
internal/testlog:
.text: 827 bytes
.noptrdata: 32 bytes
.noptrbss: 12 bytes
.bss: 16 bytes
.rodata: 72 bytes
io:
.noptrdata: 240 bytes
.bss: 272 bytes
.data: 56 bytes
.noptrbss: 0 bytes
.rodata: 128 bytes
.text: 10824 bytes
log:
.text: 188 bytes
.noptrdata: 80 bytes
.bss: 8 bytes
main:
.text: 3002 bytes
.noptrdata: 80 bytes
.rodata: 104 bytes
math:
.data: 136 bytes
.bss: 2672 bytes
.text: 184385 bytes
.noptrdata: 10211 bytes
.rodata: 2076 bytes
.noptrbss: 2 bytes
net:
.text: 24417 bytes
.noptrdata: 236 bytes
.data: 240 bytes
.bss: 584 bytes
.noptrbss: 16 bytes
.rodata: 48 bytes
os:
.bss: 264 bytes
.data: 32 bytes
.rodata: 352 bytes
.text: 46276 bytes
.noptrdata: 296 bytes
.noptrbss: 1 bytes
path:
.text: 9378 bytes
.noptrdata: 136 bytes
.bss: 48 bytes
.rodata: 48 bytes
reflect:
.noptrbss: 1 bytes
.text: 97417 bytes
.noptrdata: 72 bytes
.rodata: 1728 bytes
.data: 456 bytes
.bss: 160 bytes
regexp:
.rodata: 968 bytes
.text: 126451 bytes
.noptrdata: 558 bytes
.bss: 296 bytes
.noptrbss: 16 bytes
.data: 816 bytes
runtime:
.noptrbss: 20487 bytes
.data: 8520 bytes
.bss: 184836 bytes
.tbss: 8 bytes
.typelink: 9020 bytes
.gopclntab: 0 bytes
.text: 408713 bytes
.noptrdata: 4347 bytes
.rodata: 23102 bytes
.itablink: 2952 bytes
sort:
.text: 13055 bytes
.noptrdata: 32 bytes
.data: 16 bytes
.rodata: 24 bytes
strconv:
.text: 45928 bytes
.noptrdata: 17015 bytes
.data: 1680 bytes
.bss: 32 bytes
.rodata: 144 bytes
strings:
.text: 21070 bytes
.noptrdata: 320 bytes
.rodata: 168 bytes
sync:
.rodata: 476 bytes
.noptrdata: 56 bytes
.bss: 56 bytes
.noptrbss: 8 bytes
.text: 14288 bytes
syscall:
.noptrdata: 127 bytes
.rodata: 978 bytes
.noptrbss: 76 bytes
.bss: 264 bytes
.data: 2720 bytes
.text: 33728 bytes
text/tabwriter:
.data: 96 bytes
.rodata: 88 bytes
.text: 8002 bytes
.noptrdata: 46 bytes
text/template:
.text: 166284 bytes
.noptrdata: 316 bytes
.noptrbss: 8 bytes
.bss: 176 bytes
.data: 376 bytes
.rodata: 3152 bytes
time:
.text: 83290 bytes
.noptrdata: 164 bytes
.data: 912 bytes
.bss: 208 bytes
.noptrbss: 20 bytes
.rodata: 832 bytes
unicode:
.noptrdata: 50398 bytes
.data: 15248 bytes
.bss: 40 bytes
.noptrbss: 0 bytes
.text: 27198 bytes
注意这个程序并不完美,它只适用于 Linux/Mac,因为它依赖于 ELF。我相信您可以对 Windows PE 文件执行类似的操作,但这会花费我很多时间。
此外,该程序忽略了 go 运行时的某些部分,但我猜这对您来说不是最重要的。
关于go - 如何检查链接到我的 Go 代码中的包的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70764915/
我有一个网站,并且我使用 javascript sdk 添加了“点赞”按钮。 这是代码 (function(d, s, id) { var js, fjs = d.g
我知道 HTML 是逐行读取的。当您链接多个 css 文件(如规范化文件和样式表文件)时,由于 CSS 重要性特异性和源顺序,样式表文件应链接在规范化文件之后。看起来这不会影响链接的 JavaScri
我正在使用官方 Bootstrap site 提供的 CDN 链接在我的网络应用程序中使用面板进行测试 在彻底检查我的代码后,面板没有显示。 但是我在 SO 上看到了类似的帖子并且 CDN 链接不同
这里是编码初学者。我正在尝试为我的移动设备网站设置断点,以便我的网站适合小屏幕。我只是想检查如果我缩小视口(viewport)的宽度,背景颜色是否会改变,但没有发生任何变化。也许我只是对一个简单的错误
举一个我想要的例子,想象一下这个字符串: $text = 'lorem ipsum About us lorem ipsum'; 如果此字符串包含一个 href 以 / 开头的 anchor 链接,则
如何链接到 LaTeX 文档的另一部分或子部分?这种链接的常规范式是什么,像[链接名称]那样写,或者像网页超链接那样写? 最佳答案 链接到另一个部分需要您的部分进行一些额外的标记。要使用的命令是: \
我有一个订单表,其中包含订单号、客户 ID 和代理 ID。然后有一个带有 id 的客户表和一个带有 id 的代理表。 我需要获取所有具有来自代理 ID 'a03' 和代理 ID 'a05' 的订单的客
假设我有: dic = {"z":"zv", "a":"av"} ## Why doesn't the following return a sorted list of keys? keys = d
我在尝试链接到外部库时得到了一些奇怪的结果。如果我从命令行运行以下命令: gcc fftwTest.c -I../extlib/fftw-3.3.5-dll32 -L../extlib/fftw-3.
我认为我没有正确理解 jQuery 链接。我正在遍历一个数组并尝试将 div 元素添加到我的包装器 CSS 类中,每个 div 元素都有一个“click”类和自定义 css top 和 left 属性
HTML 使用超级链接与网络上的另一个文档相连。几乎可以在所有的网页中找到链接。点击链接可以从一张页面跳转到另一张页面。 HTML 超链接(链接) HTML使用标签 a 来设置超文本链接。 超链
这个问题在这里已经有了答案: How do I link to part of a page? (hash?) (7 个答案) Scroll Automatically to the Bottom
我想创建一个 Docker Swarm 集群,运行一个 Elasticsearch 实例、一个 MongoDB 实例和一个 grails 应用程序,每个都在单独的机器上。我正在使用 Docker Ma
我正在尝试将 CakePHP HTML Linker 用于以下代码 Add Cuisine 由于 span 标签需要在 a 标签内。我无法根据需要获得输出。关于如何完成它的任何建议? 最佳答案 禁用链
大家好, 我最近开发了一个应用程序,很快就会提交到 App Store。我想免费提交这个应用程序,并想知道我是否可以实现一个带有 PayPal 捐赠标志的按钮,上面基本上写着“捐赠用于开发”或与此相关
我想尝试在 dlang 中使用 libuv。我下载了这样的 dlang 绑定(bind): git clone git@github.com:tamediadigital/libuv.git 现在我接
我有一个节点(节点 a),各种其他节点(节点 b/c/d/e)与之引用。 我可以创建一个带有参数的 View 作为我正在查看的节点(节点 a),并获取引用该节点的节点列表。 基本上在节点 a 查看节点
我正在尝试建立一个常见问题页面,上面有目录,下面有答案。我想点击目录中的一个问题,并在同一页面上链接到相应的答案。我如何在 CakePHP 中使用 $this->Html->link() 执行此操作方
在 WooCommerce 3.0+ 中,我使用 js 创建了一些选项卡,每个选项卡中包含来自不同类别的产品。我已经设法修改了简单产品的添加到购物车链接,其中点击了 addtocart 按钮它进入下一
Delphi 2007/2009 奇怪的问题在这里: 根据设计时定义的组件属性,是否可以在链接中包含文件或保留文件? 示例:如果我将 SomeProperty 保留为真,则在编译时,单元 SomeUn
我是一名优秀的程序员,十分优秀!