分配是如何工作的,如何防止它们?

huangapple go评论84阅读模式
英文:

How do allocations work and how do you prevent them?

问题

go test工具具有一个分析器,可以告诉你代码中进行了多少次内存分配。
然而,像这样的库:
https://github.com/valyala/fasthttp
声称“热路径中没有内存分配”...这是什么意思?在Go中如何实现这一点?

英文:

The go test tool has a profiler which can tell you the amount of allocations you did inside the code.
However, seeing libraries such as this one:
https://github.com/valyala/fasthttp
stating "Zero memory allocations in hot paths"... what does that mean? and how do you achieve this in Go?

答案1

得分: 4

我个人不喜欢他们使用的语言,因为听起来像是市场营销人员会说的话...他们的意思只是说在那段代码中不会发生任何分配,因为已经提前分配了一个缓冲区来使用。

所以,明确来说,他们的意思是“在这个有限的范围内不会发生分配”。如何实现这一点?通过提前分配一个足够大的缓冲区,然后在范围内利用它。

包的作者的意图是通过提前分配来加快请求处理速度,代价是使用更多的内存(或者至少在理论上对内存有更持续的占用,缓冲区的大小可能与需要分配的大小相同)。

如果你对实现细节感兴趣,可以查看像byte_buffer.go和args.go这样的文件,你会发现提前分配了一个缓冲区对象池,这样你的处理代码就不需要为响应体等进行分配。相反,你可以从池中获取一个缓冲区(已经分配好),将响应数据写入其中,然后在完成后将其释放回池中以供重用。在标准情况下,你会为响应体分配空间,然后在返回响应后,该对象将离开作用域,内存将被释放。如上段所述,将所有这些提前移动意味着当你的服务启动时,它将获取并持有比使用net/http的类似服务更多的内存,因为后者将根据需要获取和释放内存。

英文:

I personally don't like their use of language as it sounds like something a marketer would say... All they mean to say is that no allocations will occur in that code because a buffer has been allocated in advance for use there.

So to be clear, they mean 'in this limited scope no allocations will occur'. How do you achieve this? By allocating a sufficiently large buffer in advance of that and then leveraging it in the scope.

The intent of packages author(s) is to speed up request handling by allocating up front at the cost of using more memory (or having a more constant hold on memory at least, in theory the buffer could be the same size as what would need to be allocated).

If you're curious about the implementation details take a look in files like byte_buffer.go and args.go and you'll find that there is a pool of buffer objects allocated in advance so that your handler code doesn't have to do an allocation for the response body ect. Instead you obtain a buffer from the pool (already allocated) and write the response data to it and then when you're done it's released back into the pool for reuse. In the standard scenario you'd instead allocate space for the response body and after the response is returned that object would leave scope and the memory would be freed. As I mentioned in the paragraph above, moving all of this upfront means when your service starts up it will obtain and hold a larger amount of memory than a similar service which used net/http since it will instead obtain and release memory on an as needed basis.

huangapple
  • 本文由 发表于 2016年4月30日 04:23:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/36946861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定