Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: zoufalej 12. 10. 2018, 20:58:18

Název: GO memory leak HTTP client v goroutinach
Přispěvatel: 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

Kód: [Vybrat]
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)
}

}
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: n 12. 10. 2018, 22:25:24
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:

Kód: [Vybrat]
body, err := ioutil.ReadAll(resp.Body)nebo proste zahodit:
Kód: [Vybrat]
io.Copy(ioutil.Discard, resp.Body)
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: zoufalej 12. 10. 2018, 22:36:32
zkusil jsem zahodit
Kód: [Vybrat]
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 :(


Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: Bacsa 12. 10. 2018, 22:41:14
Takhle ten alokátor pracuje. Co to dělá s nižším GOGC?
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: zoufalej 12. 10. 2018, 22:52:16
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

Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: gojazycnik 12. 10. 2018, 23:04:43
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.
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: zoufalej 12. 10. 2018, 23:21:35
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.


Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: Bacsa 12. 10. 2018, 23:39:19
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?
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: RDa 12. 10. 2018, 23:42:47
To je ten uzasny jazyk ve kterem nekdo chce psat kernel? Lol :)
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: zoufalej 12. 10. 2018, 23:44:48
2 gorutiny
2 http transporty
2 http clienty

 Ja nerozumim tomu proc ta pamet neroste kdyz gorutiny nepouziju
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: Xxxxxx 12. 10. 2018, 23:45:16
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.
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: Xxxxxx 12. 10. 2018, 23:46:49
2 gorutiny
2 http transporty
2 http clienty

 Ja nerozumim tomu proc ta pamet neroste kdyz gorutiny nepouziju

Stacky pro vlakna?
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: zoufalej 13. 10. 2018, 04:58:24
nakonec jsem mel chybu v kodu a vubec tam nema byt defer takze pamet uz nezlobi
Název: Re:GO memory leak HTTP client v goroutinach
Přispěvatel: Bacsa 13. 10. 2018, 08:59:06
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.