【发布时间】:2021-02-19 22:20:13
【问题描述】:
考虑以下 Go 代码:
type LargeStructWithNestings struct {...}
func generatorChnl() <-chan *LargeStructWithNestings { ... }
// code snippet
chnl := generatorChnl()
for entry := range chnl { // line A
doStuffWith(entry)
entry = nil // line B
}
假设通道不经常产生值,并且这些值是指向大型结构的指针,那么上面的line B 是否会导致entry 指向的内存的垃圾收集比其他情况更早发生?或者,一旦循环回到line A,entry 指向的内存中的前一个位置是否会在下一次迭代阻塞line A 时立即进行垃圾收集?
我们的目标是找到一种方法来尽可能地减少驻留集的大小。
【问题讨论】:
-
指向
entry的内存在什么时候有资格进行垃圾回收?只有在下一个条目产生/通道关闭时?还是在产生它的迭代结束时立即? -
内存在无法访问的情况下可以被回收。这更取决于
doStuffWith在您的示例中所做的事情。试图以这种方式控制 GC 通常会让你一事无成。如果你想减少内存,你需要分配更少的内存。您也可以尝试使用较低的 GOGC 设置来提高攻击性,但这也会增加 CPU 使用率和花费在 GC 上的总时间。 -
@JimB 这里的问题是在下一次迭代中:如果一个值已经存储在
entry中,并且接收另一个元素长时间阻塞,之前的元素将保留在entry中直到接收可以继续。 -
@icza:我明白你的意思,但是相同的数量会在下一次迭代中立即重新分配,并且运行时不太可能释放无论如何都会被重用的内存。
-
@CppNoob:还记得垃圾收集不会释放内存,垃圾收集器的工作是重用内存。稍早收集值并不意味着内存可以释放给操作系统。
标签: go memory-management memory-leaks garbage-collection