如何解决使用 goroutines 修复 go 程序的内存消耗
我正在解决一个涉及生产者-消费者模式的问题。我有一个生产任务的生产者和消耗任务的 'n' 个消费者。消费者任务是从文件中读取一些数据,然后将该数据上传到 S3。一个消费者最多可以读取 xMB(8/16/32) 的数据,然后将其上传到 s3。将所有数据保存在内存中导致内存消耗超过程序的预期,所以我切换到从文件中读取数据,然后将其写入某个临时文件,然后将文件上传到 S3,尽管这在内存方面,但 cpu 受到了打击。我想知道有没有什么办法可以一次性分配固定大小的内存,然后在不同的 goroutine 之间使用它? 我想要的是,如果我有 4 个 goroutine,那么我可以分配 4 个不同的 xMB 数组,然后在每个 goroutine 调用中使用相同的数组,这样 goroutine 不会每次都分配内存,也不依赖于GC 释放内存?
type struct Block {
offset int64
size int64
}
func consumer (blocks []Block) {
var dataArr []byte
for _,block := range blocks {
data := file.Read(block.offset,block.size)
dataArr = append(dataArr,data)
}
upload(dataArr)
}
我根据Blocks从文件中读取数据,这个block可以包含几个xMB限制的小块或一大块xMB。
Edit2:根据评论中的建议尝试了 sync.Pool。但我没有看到内存消耗有任何改善。我做错了什么吗?
var pool *sync.Pool
func main() {
pool = &sync.Pool{
New: func()interface{} {
return make([]byte,16777216)
},}
for i:=0; i < 4; i++ {
// blocks is 2-d array each index contains array of blocks.
go consumer(blocks[i])
}
}
go consumer(blocks []Blocks) {
var dataArr []byte
d := pool.(Get).([]byte)
for _,block := range blocks {
file.Read(block.offset,block.size,d[block.offset:block.size])
}
upload(data)
pool.put(data)
}
解决方法
看看StaticCheck的SA6002,关于sync.Pool
。您也可以使用 pprof
工具。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。