Wenn Sie den unten stehenden Code ausführen, beginnt das Programm bei etwa 1,5 Millionen und wächst dann allmählich bis zu 6,4 Millionen. Ich frage mich warum. Entfernen time.sleep behebt das Problem.Go: time.sleep und Speicherauslastung
Gibt es eine Möglichkeit, das for-select-Muster mit einem Standard zu verwenden und einige Male in der Standardeinstellung zu schlafen, ohne einen Speicher zu haben?
Aufruf runtime.GC() nach dem Schlaf repariert das Problem. Können wir dasselbe erreichen, ohne den GC anrufen zu müssen?
package main
import (
"time"
)
func main() {
c := make(chan struct{})
for {
select {
case <-c:
//some work
default:
//some work
time.Sleep(time.Millisecond * 1)
}
}
}
Gleiche mit:
package main
import (
"time"
)
func main() {
c := make(chan struct{})
for {
select {
case <-c:
case <-time.After(time.Millisecond * 10):
}
}
}
Nach einiger Zeit erforscht, ich erreichte es mit dem folgenden Code. Immer noch wundern, warum time.sleep Mem-Nutzung erhöht?
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 erhöht nicht die Speicherkapazität. Speicherverbrauch oder -nutzung, was tatsächlich verwendet wird, wann oder welcher Speicher freigegeben oder an das Betriebssystem zurückgegeben wird, ist sehr kompliziert. – Volker
Mit time.Timer hat den Trick gemacht. Ich glaube dir, wenn du sagst, dass es kompliziert ist. – user3283107
Beobachten Sie einfach die Ausgabe von gctrace, um zu sehen, was der GC macht. Schlaf erfordert eine kleine Zuteilung, und diese müssen schließlich aufgeräumt werden. Wenn Sie wirklich "arbeiten", erfordert es wahrscheinlich einige Zuordnungen, die bereinigt werden müssen. Der GC ist nicht augenblicklich, er wartet, bis ein Schwellenwert erreicht ist, bevor er ausgeführt wird, und daher wächst der Haufen etwas vor dem Abflachen. – JimB