【发布时间】:2016-03-29 12:04:30
【问题描述】:
运行下面的代码时,程序从 1.5M 左右开始,然后逐渐增长到 6.4M。我想知道为什么。 删除 time.sleep 可以解决问题。
有没有办法在默认情况下使用 for-select 模式并在默认情况下休眠一段时间而不更改任何内存?
在睡眠后调用 runtime.GC() 确实可以解决问题。我们可以在不调用 GC 的情况下实现相同的目标吗?
package main
import (
"time"
)
func main() {
c := make(chan struct{})
for {
select {
case <-c:
//some work
default:
//some work
time.Sleep(time.Millisecond * 1)
}
}
}
同理:
package main
import (
"time"
)
func main() {
c := make(chan struct{})
for {
select {
case <-c:
case <-time.After(time.Millisecond * 10):
}
}
}
经过一段时间的研究,我用下面的代码实现了它。仍然想知道为什么 time.sleep 会增加内存使用量?
package main
import (
"time"
)
func main() {
c := make(chan bool)
timer := time.NewTimer(0)
for {
select {
case <-c:
default:
timer.Reset(time.Millisecond * 1)
<-timer.C
}
}
}
【问题讨论】:
-
Time.Sleep 不会“增加内存”。内存消耗或使用,实际使用什么,何时或什么内存被释放或返回给操作系统是非常复杂的。
-
使用 time.Timer 就可以了。当你说它很复杂时,我相信你。
-
只需观察 gctrace 的输出,即可了解 GC 正在做什么。睡眠需要少量分配,最终需要清理。如果您正在做任何真正的“工作”,它可能需要一些需要清理的分配。 GC 不是即时的,它会等到达到某个阈值后再运行,因此堆在稳定之前会有所增长。