15-第15章-内存优化与对象池
·
第15章:内存优化与对象池
15.1 Go 内存管理基础
15.1.1 GC 工作原理
Go 的垃圾回收器使用三色标记清除算法:
- 标记阶段:从根对象出发,标记所有可达对象
- 清除阶段:回收未标记的对象
- 压缩阶段(可选):移动对象减少碎片
15.1.2 内存分配策略
- 小对象(< 32KB):使用 mspan 分配
- 大对象(>= 32KB):直接从 heap 分配
- 栈对象:编译器逃逸分析决定
15.2 对象池设计
15.2.1 sync.Pool 基础
// sync.Pool 使用示例
type Object struct {
Data []byte
}
var objectPool = &sync.Pool{
New: func() interface{} {
return &Object{
Data: make([]byte, 1024),
}
},
}
func GetObject() *Object {
return objectPool.Get().(*Object)
}
func PutObject(obj *Object) {
obj.Data = obj.Data[:0]
objectPool.Put(obj)
}
15.2.2 MapPool 实现
// mqtt/mapPool.go
package mqtt
import "sync"
type MapPool struct {
pool sync.Pool
}
func NewMapPool() *MapPool {
return &MapPool{
pool: sync.Pool{
New: func() interface{} {
return make(map[string]interface{}, 8)
},
},
}
}
func (p *MapPool) Get() map[string]interface{} {
return p.pool.Get().(map[string]interface{})
}
func (p *MapPool) Put(m map[string]interface{}) {
for k := range m {
delete(m, k)
}
p.pool.Put(m)
}
15.2.3 切片池
type SlicePool struct {
pool sync.Pool
size int
}
func NewSlicePool(size int) *SlicePool {
return &SlicePool{
size: size,
pool: sync.Pool{
New: func() interface{} {
return make([]interface{}, 0, size)
},
},
}
}
func (p *SlicePool) Get() []interface{} {
return p.pool.Get().([]interface{})
}
func (p *SlicePool) Put(s []interface{}) {
p.pool.Put(s[:0])
}
15.3 内存优化技巧
15.3.1 避免内存分配
// 不好的做法:循环中分配
func ProcessData(data [][]byte) {
for _, d := range data {
result := make([]byte, len(d))
copy(result, d)
// 使用 result
}
}
// 好的做法:重用缓冲区
func ProcessData(data [][]byte) {
var buf []byte
for _, d := range data {
if cap(buf) < len(d) {
buf = make([]byte, len(d))
}
buf = buf[:len(d)]
copy(buf, d)
// 使用 buf
}
}
15.3.2 字符串优化
// 避免字符串拼接
func ConcatStrings(a, b, c string) string {
return a + b + c // 会产生临时字符串
}
// 使用 strings.Builder
func ConcatStrings(a, b, c string) string {
var sb strings.Builder
sb.WriteString(a)
sb.WriteString(b)
sb.WriteString(c)
return sb.String()
}
// 预分配容量
func ConcatStrings(a, b, c string) string {
var sb strings.Builder
sb.Grow(len(a) + len(b) + len(c))
sb.WriteString(a)
sb.WriteString(b)
sb.WriteString(c)
return sb.String()
}
15.3.3 结构体优化
// 字段顺序影响内存对齐
type BadStruct struct {
a bool // 1 byte
b int64 // 8 bytes
c bool // 1 byte
} // 总共 24 bytes(有 padding)
type GoodStruct struct {
b int64 // 8 bytes
a bool // 1 byte
c bool // 1 byte
} // 总共 16 bytes(更少 padding)
15.4 内存监控
15.4.1 读取内存统计
import "runtime"
func PrintMemStats() {
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
log.Printf("Alloc = %v MiB", stats.Alloc/1024/1024)
log.Printf("TotalAlloc = %v MiB", stats.TotalAlloc/1024/1024)
log.Printf("Sys = %v MiB", stats.Sys/1024/1024)
log.Printf("NumGC = %v", stats.NumGC)
}
15.5 实战练习
练习 15.1:对象池应用
在 MQTT 客户端中应用 MapPool,减少 map 分配。
练习 15.2:内存分析
使用 pprof 分析内存使用,找出内存泄漏。
练习 15.3:优化实践
选择一个模块,应用多种内存优化技巧。
15.6 本章小结
本章深入讲解了内存优化和对象池:
- Go 内存管理基础
- sync.Pool 的使用
- 各类对象池实现
- 内存优化技巧
- 内存监控方法
合理的内存优化可以显著提升性能。
本书版本:1.0.0
最后更新:2026-03-08
sfsEdgeStore - 让边缘数据存储更简单!🚀
技术栈 - Go语言、sfsDb与EdgeX Foundry。纯golang工业物联网边缘计算技术栈
项目地址:GitHub
GitCode 镜像:GitCode
更多推荐
所有评论(0)