守着一只汪
二进制文件将包含调试符号,我们可以使用它来计算每个包占用多少空间。我编写了一个基本程序来执行此操作,因为我不知道有任何工具可以执行此操作:package mainimport ( "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 bytesbytes: .bss: 48 bytes .rodata: 64 bytes .text: 12617 bytes .noptrdata: 320 bytescompress/flate: .text: 20385 bytes .noptrdata: 248 bytes .bss: 2112 bytes .noptrbss: 12 bytes .rodata: 48 bytescompress/zlib: .text: 4138 bytes .noptrdata: 96 bytes .bss: 48 bytescontainer/list: .text: 4016 bytescontext: .text: 387 bytes .noptrdata: 72 bytes .bss: 40 bytescrypto: .text: 20982 bytes .noptrdata: 416 bytes .bss: 96 bytes .rodata: 58 bytes .noptrbss: 3 bytesdebug/dwarf: .rodata: 1088 bytes .text: 113878 bytes .noptrdata: 247 bytes .bss: 64 bytesdebug/elf: .rodata: 168 bytes .text: 36557 bytes .noptrdata: 112 bytes .data: 5160 bytes .bss: 16 bytesdebug/macho: .text: 22980 bytes .noptrdata: 96 bytes .data: 456 bytes .rodata: 80 bytesdebug/pe: .text: 26004 bytes .noptrdata: 96 bytes .rodata: 288 bytesencoding/base64: .bss: 32 bytes .rodata: 48 bytes .text: 846 bytes .noptrdata: 56 bytesencoding/binary: .text: 27108 bytes .noptrdata: 72 bytes .bss: 56 bytes .rodata: 136 bytesencoding/hex: .bss: 16 bytes .text: 288 bytes .noptrdata: 64 bytesencoding/json: .rodata: 108 bytes .text: 2930 bytes .noptrdata: 128 bytes .bss: 80 byteserrors: .rodata: 48 bytes .text: 744 bytes .noptrdata: 40 bytes .bss: 16 bytesfmt: .text: 72010 bytes .noptrdata: 136 bytes .data: 104 bytes .bss: 32 bytes .rodata: 720 bytesgithub.com/cilium/ebpf: .text: 170860 bytes .noptrdata: 1405 bytes .bss: 608 bytes .rodata: 3971 bytes .data: 16 bytes .noptrbss: 8 bytesgithub.com/go-delve/delve/pkg/dwarf/frame: .text: 18304 bytes .noptrdata: 80 bytes .bss: 8 bytes .rodata: 211 bytesgithub.com/go-delve/delve/pkg/dwarf/godwarf: .text: 40431 bytes .noptrdata: 144 bytes .rodata: 352 bytesgithub.com/go-delve/delve/pkg/dwarf/line: .bss: 48 bytes .rodata: 160 bytes .text: 24069 bytes .noptrdata: 96 bytesgithub.com/go-delve/delve/pkg/dwarf/loclist: .noptrdata: 64 bytes .rodata: 64 bytes .text: 4538 bytesgithub.com/go-delve/delve/pkg/dwarf/op: .text: 31142 bytes .noptrdata: 80 bytes .bss: 72 bytes .rodata: 5313 bytesgithub.com/go-delve/delve/pkg/dwarf/reader: .noptrdata: 72 bytes .bss: 16 bytes .rodata: 24 bytes .text: 8037 bytesgithub.com/go-delve/delve/pkg/dwarf/regnum: .bss: 40 bytes .rodata: 2760 bytes .text: 3943 bytes .noptrdata: 48 bytesgithub.com/go-delve/delve/pkg/dwarf/util: .text: 4028 bytes .noptrdata: 64 bytes .rodata: 96 bytesgithub.com/go-delve/delve/pkg/elfwriter: .text: 3394 bytes .noptrdata: 48 bytes .rodata: 48 bytesgithub.com/go-delve/delve/pkg/goversion: .noptrdata: 104 bytes .bss: 64 bytes .rodata: 160 bytes .text: 4415 bytesgithub.com/go-delve/delve/pkg/logflags: .bss: 32 bytes .rodata: 40 bytes .text: 2610 bytes .noptrdata: 136 bytes .noptrbss: 3 bytesgithub.com/go-delve/delve/pkg/proc: .text: 432477 bytes .noptrdata: 718 bytes .data: 1448 bytes .bss: 592 bytes .rodata: 10106 bytesgithub.com/go-delve/delve/pkg/version: .text: 1509 bytes .noptrdata: 72 bytes .data: 112 bytes .rodata: 40 bytesgithub.com/hashicorp/golang-lru/simplelru: .text: 3911 bytes .noptrdata: 32 bytes .rodata: 160 bytesgithub.com/sirupsen/logrus: .noptrbss: 20 bytes .rodata: 696 bytes .text: 40175 bytes .noptrdata: 204 bytes .data: 64 bytes .bss: 56 bytesgo/ast: .text: 24407 bytes .noptrdata: 104 bytes .data: 112 bytes .rodata: 120 bytesgo/constant: .bss: 8 bytes .rodata: 824 bytes .text: 33910 bytes .noptrdata: 88 bytesgo/parser: .rodata: 1808 bytes .text: 78751 bytes .noptrdata: 136 bytes .bss: 32 bytesgo/printer: .text: 77202 bytes .noptrdata: 113 bytes .data: 24 bytes .rodata: 1504 bytesgo/scanner: .rodata: 240 bytes .text: 18594 bytes .noptrdata: 93 bytes .data: 24 bytesgo/token: .noptrdata: 72 bytes .data: 1376 bytes .bss: 8 bytes .rodata: 192 bytes .text: 7154 bytesgolang.org/x/arch/arm64/arm64asm: .rodata: 856 bytes .text: 116428 bytes .noptrdata: 80 bytes .bss: 80 bytes .data: 46128 bytesgolang.org/x/arch/x86/x86asm: .noptrdata: 29125 bytes .bss: 112 bytes .data: 20928 bytes .rodata: 1252 bytes .text: 76721 bytesgolang.org/x/sys/unix: .text: 1800 bytes .noptrdata: 128 bytes .rodata: 70 bytes .data: 80 byteshash/adler32: .text: 1013 bytes .noptrdata: 40 bytesinternal/bytealg: .rodata: 56 bytes .noptrbss: 8 bytes .text: 1462 bytes .noptrdata: 32 bytesinternal/cpu: .rodata: 500 bytes .noptrbss: 416 bytes .noptrdata: 8 bytes .bss: 24 bytes .text: 3017 bytesinternal/fmtsort: .text: 7443 bytes .noptrdata: 40 bytes .rodata: 40 bytesinternal/oserror: .text: 500 bytes .noptrdata: 40 bytes .bss: 80 bytesinternal/poll: .text: 31565 bytes .rodata: 192 bytes .noptrdata: 112 bytes .data: 96 bytes .bss: 64 bytes .noptrbss: 12 bytesinternal/reflectlite: .text: 13761 bytes .noptrdata: 32 bytes .data: 456 bytes .bss: 24 bytes .rodata: 496 bytesinternal/syscall/unix: .rodata: 72 bytes .text: 708 bytes .noptrdata: 40 bytes .noptrbss: 4 bytesinternal/testlog: .text: 827 bytes .noptrdata: 32 bytes .noptrbss: 12 bytes .bss: 16 bytes .rodata: 72 bytesio: .noptrdata: 240 bytes .bss: 272 bytes .data: 56 bytes .noptrbss: 0 bytes .rodata: 128 bytes .text: 10824 byteslog: .text: 188 bytes .noptrdata: 80 bytes .bss: 8 bytesmain: .text: 3002 bytes .noptrdata: 80 bytes .rodata: 104 bytesmath: .data: 136 bytes .bss: 2672 bytes .text: 184385 bytes .noptrdata: 10211 bytes .rodata: 2076 bytes .noptrbss: 2 bytesnet: .text: 24417 bytes .noptrdata: 236 bytes .data: 240 bytes .bss: 584 bytes .noptrbss: 16 bytes .rodata: 48 bytesos: .bss: 264 bytes .data: 32 bytes .rodata: 352 bytes .text: 46276 bytes .noptrdata: 296 bytes .noptrbss: 1 bytespath: .text: 9378 bytes .noptrdata: 136 bytes .bss: 48 bytes .rodata: 48 bytesreflect: .noptrbss: 1 bytes .text: 97417 bytes .noptrdata: 72 bytes .rodata: 1728 bytes .data: 456 bytes .bss: 160 bytesregexp: .rodata: 968 bytes .text: 126451 bytes .noptrdata: 558 bytes .bss: 296 bytes .noptrbss: 16 bytes .data: 816 bytesruntime: .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 bytessort: .text: 13055 bytes .noptrdata: 32 bytes .data: 16 bytes .rodata: 24 bytesstrconv: .text: 45928 bytes .noptrdata: 17015 bytes .data: 1680 bytes .bss: 32 bytes .rodata: 144 bytesstrings: .text: 21070 bytes .noptrdata: 320 bytes .rodata: 168 bytessync: .rodata: 476 bytes .noptrdata: 56 bytes .bss: 56 bytes .noptrbss: 8 bytes .text: 14288 bytessyscall: .noptrdata: 127 bytes .rodata: 978 bytes .noptrbss: 76 bytes .bss: 264 bytes .data: 2720 bytes .text: 33728 bytestext/tabwriter: .data: 96 bytes .rodata: 88 bytes .text: 8002 bytes .noptrdata: 46 bytestext/template: .text: 166284 bytes .noptrdata: 316 bytes .noptrbss: 8 bytes .bss: 176 bytes .data: 376 bytes .rodata: 3152 bytestime: .text: 83290 bytes .noptrdata: 164 bytes .data: 912 bytes .bss: 208 bytes .noptrbss: 20 bytes .rodata: 832 bytesunicode: .noptrdata: 50398 bytes .data: 15248 bytes .bss: 40 bytes .noptrbss: 0 bytes .text: 27198 bytes注意这个程序并不完美,它只适用于 Linux/Mac,因为它依赖于 ELF。我相信您可以对 Windows PE 文件执行类似的操作,但这会花费我很多时间。此外,这个程序忽略了 go 运行时的某些部分,但我猜这对你来说不是最重要的。