上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
- 1. 初始化
- 2. 内存分配
- 3. 垃圾回收
- 4. 并发调度
- 5. 通道
- 6. 延迟调用
- 7. 终结器
- 8. 其他
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
编译
编译不仅仅是执行 go build
命令,还有些额外内容。
- 调试 :
-gcflags "-N -l"
,阻止优化和内联。 - 发布 :
-ldflags "-w -s"
,剔除符号表和调试信息。
1. 编译指令
编译指令(#pragmas)非语言规范内容,由编译器实现,指示对代码做 “特殊” 处理。
//go:noinline
: 阻止内联。//go:nosplit
: 不插入 morestack 指令。(栈检查和扩容)
注意,
//go
之间不能有空格,避免和注释(comment)冲突。使用编译指令阻止具体某个函数内联,这与
-gcflags "-l"
全局不同。
package main //go:noinline //go:nosplit func test() { println("hello, world!") } func main() { test(); }
$ go build -o test $ go tool objdump -s "main\.test" ./test TEXT main.test(SB) main.go:5 SUBQ $0x18, SP main.go:5 MOVQ BP, 0x10(SP) main.go:5 LEAQ 0x10(SP), BP main.go:6 CALL runtime.printlock(SB) main.go:6 LEAQ 0xd7a4(IP), AX main.go:6 MOVL $0xe, BX main.go:6 NOPL main.go:6 CALL runtime.printstring(SB) main.go:6 CALL runtime.printunlock(SB) main.go:7 MOVQ 0x10(SP), BP main.go:7 ADDQ $0x18, SP main.go:7 RET
2. 编译时间
不修改源码,动态调整某些内容。比如编译时间、自增版本号等。
// github.com/qyuhen/my; a.go package my var buildTime string
$ go build -ldflags "-X github.com/qyuhen/my.buildTime=$(date +'%Y%m%d-%H%M%S')"
3. 类型信息
编译器将类型信息存储到 .rodata
段,以 lea
指令加载。
package main type data struct { x int } func main() { m := make(map[string]data) m["a"] = data{} }
$ go build -gcflags -S 2>a.txt # 输出到文件,便于查看。 "".main STEXT LEAQ type.map[string]"".data(SB), AX type.map[string]"".data SRODATA 0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 0x0010 65 42 fb e0 02 08 08 35 00 00 00 00 00 00 00 00 0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0050 10 08 d0 00 0c 00 00 00 rel 32+8 t=1 runtime.gcbits.01+0 rel 40+4 t=5 type..namedata.*map[string]main.data-+0 rel 44+4 t=- type.*map[string]"".data+0 rel 48+8 t=1 type.string+0 rel 56+8 t=1 type."".data+0 rel 64+8 t=1 type.noalg.map.bucket[string]"".data+0 rel 72+8 t=1 runtime.strhash·f+0
链接器将引用符号(
rel
)数据(1 = R_ADDR
)填充到上面(十六进制数据)偏移+长度
位置。
类型(
t
)参考src/cmd/internal/objabi/reloctype.go
。数据段(
STEXT
,SRODATA
)参考src/cmd/internal/objabi/symkind.go
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论