亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Echo 或 Gin 框架的大型數組的內存消耗

使用 Echo 或 Gin 框架的大型數組的內存消耗

Go
桃花長相依 2023-06-26 17:09:52
當我嘗試用 Echo(還有 Gin)發送一個大數組時,我遇到了內存問題。請求后,內存并未釋放。package mainimport (    "net/http"    "strconv"    "github.com/labstack/echo")type User struct {    Username  string    Password  string    Lastname  string    Firstname string}func main() {    e := echo.New()    e.GET("/", func(c echo.Context) error {        var user User        users := make([]User, 0)        for i := 0; i < 100000; i++ {            user = User{                Username:  "ffgfgfghhfghfhgfgfhgfghfghfhgfhgfh" + strconv.Itoa(i),                Password:  "gjgjghjgjhgjhghjfrserhkhjhklljjkbhjvftxersgdghjjkhkljkbhftd",                Lastname:  "njuftydfhgjkjlkjlkjlkhjkhu",                Firstname: "jkggkjkl,,lm,kljkvgf"}            users = append(users, user)        }        defer func() {            users = nil        }()        return c.JSON(http.StatusOK, users)    })    e.Logger.Fatal(e.Start(":1323"))}為了測試,我并行運行請求,得到以下結果:1 個請求:300Mo5 個請求:1.5Go10 個請求:3.1Go更多:我的電腦死機了:)如何減少內存消耗?
查看完整描述

1 回答

?
森林海

TA貢獻2011條經驗 獲得超2個贊

分配的內存不會立即返回給操作系統,

您的答案幾乎沒有改進,因為您仍在內存中構建(Go)數組(或更確切地說切片),并且一旦完成,您才可以繼續將其編組到響應中。您還可以為每個項目創建一個新的編碼器,編組單個項目,然后將其丟棄。您可以用來json.Encoder整理多個項目。您還可以在每個項目之后刷新響應,這也是非常低效的。這違背了所有內部緩沖的目的......

相反,您可以在項目 (?User) 準備好后立即對它們進行編組,這樣您就不必將所有內容都保留在內存中。并且不要在每個用戶之后刷新,最后執行一次就足夠了,這是沒有必要的,因為一旦您從處理程序返回,服務器將刷新所有緩沖的數據。

這樣做:

e.GET("/", func(c echo.Context) error {

? ? c.Response().WriteHeader(http.StatusOK)


? ? enc := json.NewEncoder(c.Response())

? ? for i := 0; i < 100000; i++ {

? ? ? ? user := User{

? ? ? ? ? ? Username:? "ffgfgfghhfghfhgfgfhgfghfghfhgfhgfh" + strconv.Itoa(i),

? ? ? ? ? ? Password:? "gjgjghjgjhgjhghjfrserhkhjhklljjkbhjvftxersgdghjjkhkljkbhfd",

? ? ? ? ? ? Lastname:? "njuftydfhgjkjlkjlkjlkhjkhu",

? ? ? ? ? ? Firstname: "jkggkjkl,,lm,kljkvgf",

? ? ? ? }

? ? ? ? if err := enc.Encode(user); err != nil {

? ? ? ? ? ? return err

? ? ? ? }

? ? }


? ? return nil

})

這里需要注意一點:上面的代碼不會將 JSON 數組發送到輸出,而是發送一系列 JSON 對象。如果這不適合您并且您確實需要發送單個 JSON 數組,只需“框架”數據并在項目之間插入逗號:


e.GET("/", func(c echo.Context) error {

? ? resp := c.Response()

? ? resp.WriteHeader(http.StatusOK)


? ? if _, err := io.WriteString(resp, "["); err != nil {

? ? ? ? return err

? ? }

? ? enc := json.NewEncoder(resp)

? ? for i := 0; i < 100000; i++ {

? ? ? ? if i > 0 {

? ? ? ? ? ? if _, err := io.WriteString(resp, ","); err != nil {

? ? ? ? ? ? ? ? return err

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? user := User{

? ? ? ? ? ? Username:? "ffgfgfghhfghfhgfgfhgfghfghfhgfhgfh" + strconv.Itoa(i),

? ? ? ? ? ? Password:? "gjgjghjgjhgjhghjfrserhkhjhklljjkbhjvftxersgdghjjkhkljkbhft",

? ? ? ? ? ? Lastname:? "njuftydfhgjkjlkjlkjlkhjkhu",

? ? ? ? ? ? Firstname: "jkggkjkl,,lm,kljkvgf",

? ? ? ? }

? ? ? ? if err := enc.Encode(user); err != nil {

? ? ? ? ? ? return err

? ? ? ? }

? ? }

? ? if _, err := io.WriteString(resp, "]"); err != nil {

? ? ? ? return err

? ? }


? ? return nil

})


查看完整回答
反對 回復 2023-06-26
  • 1 回答
  • 0 關注
  • 193 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號