golang 切片中的内存泄漏

Memory leak in golang slices of slices

我读到如果你有一个指针切片并且你删除了最后一个指针元素,它指向的项目将不会在内存中被释放,因为他的指针仍然存在于底层数组中。所以你有一个切片 []*int 你应该这样做

y,z:= 1,2
var x []*int = []*int{&y,&z}
x[1] = nil // otherwize z will not be freed 
x = x[:1] 

所以我的问题是:由于切片是引用类型,[][]int也会出现这种情况吗?删除最后一个切片时是否应该将其归零?

每个切片都指向一个支持数组。 Go 垃圾收集器不查看活动切片。它只查看分配内存中存在的指针,这将是整个数组,即使您只有其中一个元素的活动切片。

无论如何,是的,一个切片包含一个 reference/pointer,它在 GC 期间使整个后备数组保持活动状态。

如果您长期保留该后备数组,并且该数组包含指针或切片,那么是的,您需要将它们设置为 nil。

根据我使用 Go 编写的服务的经验,您可以通过决定要使用多少 RAM 并分配固定大小的数组来做得更好。也许您认为 100 MB 是一个很好的数量,因此您在一个由固定大小结构组成的固定大小数组中分配了 80 MB。任何溢出的请求都会被拒绝。或者,如果您的请求槽已满,请延迟处理它,直到早期请求完成。

或者让每个处理程序 goroutine 分配一个固定大小的持久结构,而不是结构数组,以便在它通过其通道接收每个请求时使用。然后在服务启动时启动固定数量的 goroutine 处理程序。

无论如何...垃圾收集是你的敌人。如果你不分配内存,它不会运行。因此,只需预先分配一次,避免过多的内存分配,然后您就不会遇到奇怪的 GC 暂停和 GC 消耗您的 CPU 时间。不要过度避免它,但是逃逸函数范围的大量嵌套指针是一个非常糟糕的主意。