Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah permintaan siaran http memberi saya penggunaan memori yang tinggi dalam pergi?

Mengapakah permintaan siaran http memberi saya penggunaan memori yang tinggi dalam pergi?

PHPz
PHPzke hadapan
2024-02-14 15:24:08931semak imbas

为什么 http post 请求在 go 中给我带来很高的内存使用率?

Editor PHP Xinyi menemui masalah penggunaan memori yang tinggi apabila menggunakan bahasa Go untuk membuat permintaan siaran http. Soalan ini mencetuskan pemikirannya, kenapa perkara ini berlaku? Selepas penyelidikan dan analisis, beliau menemui beberapa kemungkinan punca dan mencadangkan beberapa penyelesaian. Dalam artikel ini, kami akan menyelidiki soalan ini dan memberikan jawapan.

Kandungan soalan

Saya mempunyai go aplikasi berjalan di dalam bekas k8s. Ia berfungsi sebagai api rehat, menerima permintaan dan menulisnya ke elasticsearch.

Kod saya ialah:

var r = gin.default()
r.post("/logs", func(c *gin.context) {
        fmt.println("receive log event")
        printmemusage()
        jsondata, err := ioutil.readall(c.request.body)
        d := strings.newreader(jsondata)
        http.post(fmt.sprintf("%s/_bulk", geteshost()), "application/json", d)
        ...
    })
}


Dalam kod di atas, yang mendengar laluan /logs 并调用 http 将数据保存到 elasticsearch 中。当我使用下面的函数打印内存使用情况时,我可以看到 alloc 不断增加,直到内存耗尽。如果我删除 http.post panggilan, penggunaan memori sentiasa 1 hingga 3mb. Apakah yang boleh menjadi sebab penggunaan memori yang semakin meningkat?

func bToMb(b uint64) uint64 {
    return b / 1024 / 1024
}
func PrintMemUsage() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    // For info on each, see: https://golang.org/pkg/runtime/#MemStats
    fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
    fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
    fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
    fmt.Printf("\tNumGC = %v\n", m.NumGC)
}

Penyelesaian

http dokumentasidisebut berkali-kali:

Pelanggan mesti menutup badan respons apabila selesai:

Ini contoh daripada dokumentasi:

resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
// ...

Jika anda tidak melakukan ini, kebocoran akan berlaku kerana badan akan kekal dalam ingatan selama-lamanya.

Atas ialah kandungan terperinci Mengapakah permintaan siaran http memberi saya penggunaan memori yang tinggi dalam pergi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam