优化
go 内存优化
- 减少堆内存分配,尽量到栈上。
- 复用对象(对象池)
- 预分配切片/Map
- 数据结构优化
- 调整字段顺序:利用内存对齐减少填充空隙。
- 使用unsafe 手动管理内存,如解析协议时避免类型转换。
- 调整GC触发阈值
- 长期存活的对象提升为全局变量,避免反复分配。
参数化分析
- -gcflags=-m :查看编译器的逃逸分析和内联决定
- GODEBUG=gctrace=1 :开启gc跟踪
具体优化
- string与byte的转化,会在底层发生内存拷贝,直接修改指针
func Str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0],x[1],x[1]}
return*(*[]byte)(unsafe.Pointer(&h))
}
func Bytes2str(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
- map 会按需扩张,但须付出数据拷贝和重新哈希成本。如有可能,应尽可能预设足够容量空间,避免此类行为发生
m := make(map[string]int,10)
- 对于小对象,直接将数据交由 map 保存,远比用指针高效。这不但减少了堆内存分配,关键还在于垃圾回收器不会扫描非指针类型 key/value 对象
m := make(map[string]int,10) //值数据
m := make(map[string]*int,10) //指针数据
-
对于map类型,delete不会减少内存占用,只有将map至为nil才会释放内存
-
闭包会导致变量逃逸到堆上,造成GC负担,同时闭包会增加开销
-
对于压力很大的内部组件之间,用接口有些得不偿失,普通调用用内联