gpt4 book ai didi

memory - 在 Go 中处理包分配的最佳实践

转载 作者:IT王子 更新时间:2023-10-29 02:24:39 26 4
gpt4 key购买 nike

我正在编写一个包,它在内部大量使用缓冲区进行临时存储。我有一个全局(但未导出)字节 slice ,它从 1024 个元素开始,并根据需要加倍增长。

但是,我的包的用户很可能会以导致分配大缓冲区的方式使用它,然后停止使用该包,从而浪费大量已分配的堆空间,我会无法知道是否释放缓冲区(或者,因为这是 Go,让它被 GC'd)。

我想到了三种可能的解决方案,但没有一种是理想的。我的问题是:在这种情况下,这些解决方案中的任何一个,或者我可能没有想到的解决方案,都是标准做法吗?有没有标准的做法?还有其他想法吗?

  1. 去他的。

好吧。处理这个问题太难了,将分配的内存留在身边并不是那么坏的。

这种方法的问题很明显:它不能解决问题。

  1. 导出“I'm done”或“Shrink internal memory usage”功能。

导出一个用户可以调用的函数(智能地调用它显然取决于他们),这将释放包使用的内部存储空间。

这种方法的问题是双重的。首先,它为用户提供了一个更复杂、更不简洁的界面。其次,用户可能不可能或不切实际地知道何时调用这样的函数是明智的,因此无论如何它都可能毫无用处。

  1. 运行一个 goroutine,它会在包闲置一段时间后释放缓冲区,或者只要缓冲区的大小有一段时间没有增加就会缩小缓冲区(可能将长度减半)。

这种方法的问题主要在于它给调度程序带来了不必要的压力。显然,单个 goroutine 并没有那么糟糕,但是如果这是公认的做法,那么如果您导入的每个包都在后台执行此操作,那么它就不会很好地扩展。此外,如果您有一个时间敏感的应用程序,您可能不希望代码在您不知道的情况下运行(也就是说,您可能假设该程序包在其功能未被调用时未执行任何工作 - a合理的假设,我会说)。

那么……有什么想法吗?

注意:您可以看到现有项目here (相关代码只有几十行)。

最佳答案

一个常见的方法是让客户端将现有的 []byte(或其他)作为参数传递给某些调用/函数/方法。例如:

// The returned slice may be a sub-slice of dst if dst was large enough
// to hold the entire encoded block. Otherwise, a newly allocated slice
// will be returned. It is valid to pass a nil dst.
func Foo(dst []byte, whatever Bar) (ret []byte, err error)

( Example )

另一种方法是从 a 中获取一个新的 []byte,例如 cache和/或例如 pool (如果您更喜欢该概念的后一个名称)并依赖客户端将使用过的缓冲区返回到此类“回收站”。

顺便说一句:考虑到这一点,您就做得对了。如果可以合理地重用 []byte 缓冲区,就有可能降低 GC 负载,从而使您的程序性能更好。有时差异可能很关键。

关于memory - 在 Go 中处理包分配的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18047724/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com