2017-02-20 3 views
2

Ich benutze goroutines in einem Paket, wo es einen TCP-Server gibt. Die Antwort ist meistens sehr schwer, aber wenn die Routinen enden, wird sie nicht aus dem Speicher gelöscht.FreeOSMemory() in der Produktion

func Handle() { 
    service := ":7777" 
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service) 
    checkError(err) 
    listener, err := net.ListenTCP("tcp", tcpAddr) 
    checkError(err) 
    defer listener.Close() 

    for { 
     conn, err := listener.Accept() 
     checkError(err) 
     go handleRequest(conn, db) 

    } 
} 

func handleRequest(conn net.Conn, db *sql.DB) { 
    message := make([]byte, 0, 4096) 
    tmp := make([]byte, 256) 
    n, err := conn.Read(tmp) 
    if err != nil { 
     if err != io.EOF { 
      fmt.Println("read error:", err) 
     } 
    } 
    message = append(message, tmp[:n]...) 
    fmt.Println("Message Received:", string(message)) 
    // do something to get resp 
    conn.Write(append(resp, []byte("\n")...)) 
    conn.Close() 
    debug.FreeOSMemory() 
    return 
} 

Also in diesem Fall die Antwort ist groß, und ein goroutine 10% des Speichers verwendet wird, das ist in Ordnung, weil ich 170.000 Benutzer aus der Datenbank erhalten und das Ergebnis zu JSON analysieren. Aber wenn die HandleRequest und es noch im Speicher ist, wenn ich nicht debug.FreeOsMemory() verwenden. Ich habe Zweifel, es ist ein guter Weg, es zu tun, weil es in der Debug-Pacakge ist, so meine Frage ist es ein guter Weg, um den Speicher zu leeren, was die Göroutinen verwenden? Ich habe es getestet, so dass es nicht auf das System einwirkt und sehr gut funktioniert. Wenn nicht, was ist der gute Weg? Ich kann den GC nicht erwarten, um es aufzuräumen ?! Ich lese this und deshalb habe ich begonnen, es zu verwenden, in der ersten Antwort gibt es den letzten Vorschlag.

+0

„es ist ein guter Weg, um den Speicher zu leeren, was die goroutines verwenden“. Antwort: Nein, halte dich von solchen Hacks fern, vor allem, weil sie nicht hilfreich sind. – Volker

+0

@Volker Zuerst, warum habe ich eine Down-Abstimmung bekommen? Zweitens, was ist dann der gute Weg? – PumpkinSeed

Antwort

4

Die Go-Laufzeit entbindet nicht freie Speicher zurück zum O „sofort“, wäre es ineffizient sein. Lesen Sie mehr darüber hier: Golang - Cannot free memory once occupied by bytes.Buffer.

Sie sollten die Go-Laufzeit behandeln lassen. Wenn Ihre App instabil ist, ohne debug.FreeOsMemory() anzurufen, gibt es größere Probleme, die Sie nicht vertuschen sollten, auch wenn es "scheinbar" hilft. Es kann sogar die Situation verschlimmern, als ob das Bedienen einer Anfrage eine große Menge an Speicher benötigt (der vom GC ordnungsgemäß freigegeben wird, wenn er mit der Anfrage fertig ist), wobei FreeOsMemory() nur an das Betriebssystem zurückgesendet wird, welches die Laufzeit anfordern muss für/erneut zuweisen, wenn eine andere Anfrage bedient wird. Wenn Sie es nicht an das Betriebssystem zurückgegeben haben, wäre es für die nächste Anforderung verfügbar ...

Versuchen Sie, die Speicheranforderungen des Anforderungshandlers zu verringern. Wenn dies nicht möglich ist (fraglich), schränken Sie die Anzahl der Anforderungen ein, die großen Arbeitsspeicher erfordern, der gleichzeitig ausgeführt werden kann.

diese Frage Siehe + beantworten, wie das zu tun: Process Management for the Go Webserver

auch: Is this an idiomatic worker thread pool in Go?

+0

Danke, der Service stabil ohne das FreeOSMemory, ich weiß nur nicht, ob es ein guter Weg ist oder nicht. Jetzt habe ich einen Anhaltspunkt dafür. – PumpkinSeed

3

GO lang sauber allen Speicher, der nicht verwendet wird, aber nicht sofort ist. Sie können die andere Frage lesen:

Golang - Cannot free memory once occupied by bytes.Buffer

+0

Ja, ich lese das, deshalb habe ich begonnen, dieses Paket zu benutzen, aber ich habe Zweifel wegen des Hauptpaketnamens, das ist es der gute Weg? – PumpkinSeed

+0

Ist der gute Weg, wenn Sie den Speicher sofort benötigen, aber Force Drop-Speicher ist in allen Programmiersprachen gefährlich. –

Verwandte Themen