Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: zoufalej 12. 10. 2018, 20:58:18
-
jsem v Go novy a zkousim tento priklad
https://gobyexample.com/worker-pools
akorat jsem si tam zkusil dat net/http ze standardni knihovny a leakuje mi pamet silenym zpusobem
1) zaviram resp.Body.Close()
2) taky se podivejte ze clienta a transport zkousim vytvorit mimo for loop
presto to leakuje pamet jak blazen!
poradte prosim proc to leakuje
package main
import (
"fmt"
"net/http"
"time"
)
func check2(id int,jobs <- chan string,results chan <- string) (){
// nevytvarim pokazde transport ani klienta
tr := &http.Transport{DisableCompression:true, DisableKeepAlives:true}
myClient := &http.Client{
Transport: tr,
Timeout: time.Second * 10,
}
//--------------------------------------------------
for url := range jobs {
start := time.Now()
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return
}
req.Header.Set("User-Agent", "Leak test")
resp, err := myClient.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
results <- fmt.Sprintf("X-goroutine_id %d => %s %s",id,url,time.Since(start))
time.Sleep(time.Millisecond*100) //wait before next iteration
}
}
func main() {
//go build -ldflags="-s -w" -o tt.exe leak2.go && tt.exe
var max = 5000
in := make(chan string, max)
out := make(chan string, max)
for i:=0;i<max;i++{
in <- "http://127.0.0.1:5000/"
}
close(in)
for i:=0;i<2;i++{
go check2(i+1,in,out)
}
for i:=0;i<max;i++{
fmt.Printf("%s\n", <-out)
}
}
-
Jen jsem to zbezne proletl, ale u standardniho Go http klienta musis response body pred zavrenim kompletne precist (a treba zahodit)
Bud precist treba tak jak ti rikaji v dokumentaci:
body, err := ioutil.ReadAll(resp.Body)nebo proste zahodit:
io.Copy(ioutil.Discard, resp.Body)
-
zkusil jsem zahodit
io.Copy(ioutil.Discard, resp.Body)
defer resp.Body.Close()
i obracene a ta pamet procesu nonstop narusta. Musi to byt tim http clientem, protoze kdyz ho dam pryc tak to nedela, resp. jen trochu na startu a pak se to stabilizuje. S tim http clientem to zere kazdym zavolanim kb pameti :(
-
Takhle ten alokátor pracuje. Co to dělá s nižším GOGC?
-
nastavil jsem si pri kompilaci GOGC=1 a dela to stale :(
Jeste musim dodat, ze jsem to taky zkousel bez goroutin a channelu jen ve smycce a bud se to nedelo vubec nebo to bylo zanedbatelne
-
https://golang.org/pkg/runtime/
Defaultne sa pamat bude uvolnovat az ked dojde. Kolko mas volnej pamate a kolko ti "leakuje"? Ak mas 1G a leakuje ti 1M tak ani GOGC=1 nestaci na spustenie gc.
-
no ja ted zacal i volat runtime.GC() a je to uplne beze zmeny! :(
ja bych potreboval aby ten program byl co nejuspornejsi.
Ted mam treba 2gb volne pameti a ten program naroste do 100mb a furt roste dal.
-
no ja ted zacal i volat runtime.GC() a je to uplne beze zmeny! :(
ja bych potreboval aby ten program byl co nejuspornejsi.
Ted mam treba 2gb volne pameti a ten program naroste do 100mb a furt roste dal.
Kolik to celkem použije goroutin?
-
To je ten uzasny jazyk ve kterem nekdo chce psat kernel? Lol :)
-
2 gorutiny
2 http transporty
2 http clienty
Ja nerozumim tomu proc ta pamet neroste kdyz gorutiny nepouziju
-
To je ten uzasny jazyk ve kterem nekdo chce psat kernel? Lol :)
Ty jsi jouda, kdyz v tom chce nekdo psat kernel, tak si musi udelat sam obsluhu pameti a pak uz je Go a C prasta jako uhod.
-
2 gorutiny
2 http transporty
2 http clienty
Ja nerozumim tomu proc ta pamet neroste kdyz gorutiny nepouziju
Stacky pro vlakna?
-
nakonec jsem mel chybu v kodu a vubec tam nema byt defer takze pamet uz nezlobi
-
nakonec jsem mel chybu v kodu a vubec tam nema byt defer takze pamet uz nezlobi
Tak defer se použít může, ale ve zvláštní funkci, aby se provedlo dříve.