2016-03-29 16 views
-3

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 
     } 
    } 
} 
+2

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

+0

Mit time.Timer hat den Trick gemacht. Ich glaube dir, wenn du sagst, dass es kompliziert ist. – user3283107

+1

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

Antwort

-2

Nach einiger Zeit Recherche habe ich es mit dem folgenden Code erreicht.

-1

Sie können von einen Timeout mit einem select und erhalten implementieren:

select { 
    case res := <-c: 
    fmt.Println("do some work") 
    case <-time.After(time.Second * 1): 
    fmt.Println("timeout") 
} 

Im Fall, dass Sie verstehen, wie Ihr Programmspeicher verwendet, wird Sie Profilierungs tun können. Here ist ein schöner Artikel zu diesem Thema.

+0

Entfernen Sie den 'default:' und verwenden Sie stattdessen 'case <-time.After (time.Millisecond * 10):' noch die Mem-Nutzung im Laufe der Zeit zu erhöhen. Ich denke, es ist etwas internes zum Zeitpunkt pkg. – user3283107