0

我正在研究一个涉及生产者-消费者模式的问题。我有一个生产任务的生产者和消费任务的“n”个消费者。消费者任务是从文件中读取一些数据,然后将该数据上传到 S3。一位消费者可以读取多达 xMB(8/16/32) 的数据,然后将其上传到 s3。将所有数据保留在内存中导致内存消耗超过程序的预期,因此我切换到从文件中读取数据,然后将其写入某个临时文件,然后将文件上传到 S3,尽管这在内存方面,但CPU受到了打击。我想知道是否有任何方法可以一次分配固定大小的内存,然后在不同的 goroutines 中使用它?我想要的是,如果我有 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)  
}

我从基于块的文件中读取数据,这个块可以包含几个受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)
}
4

1 回答 1

0

看看StaticCheck的 SA6002,关于sync.Pool. 您也可以使用pprof工具。

于 2021-06-27T02:13:50.587 回答