Maison > développement back-end > Golang > Pourquoi les requêtes de publication http me permettent-elles d'utiliser beaucoup de mémoire ?

Pourquoi les requêtes de publication http me permettent-elles d'utiliser beaucoup de mémoire ?

PHPz
Libérer: 2024-02-14 15:24:08
avant
962 Les gens l'ont consulté

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

L'éditeur PHP Xinyi a découvert le problème de l'utilisation élevée de la mémoire lors de l'utilisation du langage Go pour effectuer des requêtes de publication http. Cette question a déclenché sa réflexion, pourquoi cela arrive-t-il ? Après recherche et analyse, il a trouvé quelques causes possibles et proposé des solutions. Dans cet article, nous approfondirons cette question et apporterons une réponse.

Contenu de la question

J'ai une application go exécutée dans un conteneur k8s. Il fonctionne comme une API de repos, recevant des requêtes et les écrivant dans elasticsearch.

Mon code est :

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)
        ...
    })
}


Copier après la connexion

Dans le code ci-dessus, qui écoute les appels path /logs 并调用 http 将数据保存到 elasticsearch 中。当我使用下面的函数打印内存使用情况时,我可以看到 alloc 不断增加,直到内存耗尽。如果我删除 http.post, l'utilisation de la mémoire est toujours de 1 à 3 Mo. Quelle pourrait être la raison de l’utilisation croissante de la mémoire ?

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)
}
Copier après la connexion

Solution

documentation httpmentionnée à plusieurs reprises :

Le client doit fermer le corps de la réponse une fois terminé :

Voici un exemple tiré de la documentation :

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

Si vous ne le faites pas, des fuites se produiront car le corps restera en mémoire pour toujours.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal