跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • golang http 内存泄漏的问题
未分類
23 2 月 2021

golang http 内存泄漏的问题

golang http 内存泄漏的问题

資深大佬 : chenqh 2

代码

package main  import (  "crypto/tls"  "io/ioutil"  "log"  "net/http"  "os"  "path"  "strings"  "time" )  func panicIfNotNil(e error) {  if e != nil {   panic(e)  } }  func loop() {  ex, err := os.Executable()  panicIfNotNil(err)   ex = path.Dir(ex)  for {   now := time.Now()   tr := &http.Transport{    TLSClientConfig:   &tls.Config{InsecureSkipVerify: true},    DisableKeepAlives: true, // 可以关闭链接   }   req, err := http.NewRequest("GET", "https://httpbin.org/ip", nil)   panicIfNotNil(err)   client := &http.Client{    Timeout:   time.Second * 8,    Transport: tr,   }    resp, err := client.Do(req)    if resp != nil {    bodyByteArr, err := ioutil.ReadAll(resp.Body)    panicIfNotNil(err)     log.Printf("status_code:%d, body:%s, cost:%v", resp.StatusCode, string(bodyByteArr), time.Since(now))    defer resp.Body.Close()   }   if err != nil && strings.Index(err.Error(), "Client.Timeout exceeded while awaiting headers") > -1 {    continue   }   panicIfNotNil(err)    time.Sleep(time.Second * 3)   } }  func main() {  loop() }  

一开始只有 4-m 的样子,过了两分钟就到 10M 左右了,这是为什么呀,我可能确保链接时关闭了的 求大佬指点下

大佬有話說 (21)

  • 資深大佬 : jworg

    没细看代码,但看到 transport,这有一篇文章, http://www.linvon.cn/posts/go-transport-%E9%95%BF%E8%BF%9E%E6%8E%A5%E5%AF%BC%E8%87%B4-goroutine-%E6%B3%84%E9%9C%B2/

  • 資深大佬 : jinliming2

    defer resp.Body.Close() 只会在 func 推出后执行,你这里一直在死循环,函数不推出,resp.Body.Close() 永远不会执行。
    你这里直接把 defer 去掉应该就好了。

  • 資深大佬 : Mohanson

    for 循环里面 defer,上正解

  • 主 資深大佬 : chenqh

    @jinliming2 去掉了 defer 内存也在涨

  • 主 資深大佬 : chenqh

    @Mohanson 去掉了也在涨呀

  • 主 資深大佬 : chenqh

    [[email protected] simple]$ go version
    go version go1.15.3 linux/amd64

  • 資深大佬 : jinliming2

    emmmm,看上去应该没有其他泄露的地方了,你 keepAlive 关了,应该不用手动 CloseIdleConnections 了。
    建议你再观察观察,因为你这个是一直在循环,你多观察一会,它是会一直增长,还是会停留在一定程度?
    如果涨到一定程度就不涨了,那可能就跟 go 的垃圾回收机制有关了。

  • 主 資深大佬 : chenqh

    @jinliming2 现在已经 11m 了

    “`
    Every 2.0s: ~/soft/pstat –name=”simple” –exclude=”pstat” Sat Mar 6 22:57:49 2021

    name count mem open_files net_connections
    —- —– — ———- —————
    simple 1 11.03m 20 0

    “`

  • 主 資深大佬 : chenqh

    @jinliming2 难道大佬们都是全局 client 的吗?

  • 資深大佬 : jworg

    我还是直接把 Transport 中注释贴出来吧,你看看你创建了多少个,正常应该 reused 的

    // Transport is an implementation of RoundTripper that supports HTTP,
    // HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).
    //
    // By default, Transport caches connections for future re-use.
    // This may leave many open connections when accessing many hosts.
    // This behavior can be managed using Transport’s CloseIdleConnections method
    // and the MaxIdleConnsPerHost and DisableKeepAlives fields.
    //
    // Transports should be reused instead of created as needed.
    // Transports are safe for concurrent use by multiple goroutines.
    //
    // A Transport is a low-level primitive for making HTTP and HTTPS requests.
    // For high-level functionality, such as cookies and redirects, see Client.

  • 主 資深大佬 : chenqh

    @jworg

    “`
    [[email protected] simple]$ sudo lsof -p 9575 -a -i 4
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    simple 9575 vagrant 6u IPv4 6958222 0t0 TCP localhost.localdomain:38460->ec2-34-231-30-52.compute-1.amazonaws.com:https (ESTABLISHED)
    “`

    只有一个

  • 主 資深大佬 : chenqh

    现在好像卡在 11.39 不动了

    “`
    Every 2.0s: ~/soft/pstat –name=”simple” –exclude=”pstat” Sat Mar 6 23:50:46 2021

    name count mem open_files net_connections
    —- —– — ———- —————
    simple 1 11.39m 20 0

    “`

    明天在看一下

  • 資深大佬 : jworg

    @chenqh 我之前回复弄错了,没有仔细看代码。我这边是在 11M 到 12M 波动,应该如 7 所说。另外建议安装代码检查工具,可以提示那个 defer 以及 resp.Body.Close()的返回值的检查。

  • 資深大佬 : Immortal

    pprof 打开观察下就好了 何必在这里猜
    代码看起来没啥问题 defer 的问题前面也有人说了

  • 資深大佬 : nanmu42

    你再测久一些试试看,12M 还太少了。
    比如 10 个小时后到了 100M,那才是真的漏了。

    Go 1.16 之前,不用的内存还给操作系统的时机都比较延后,你也可以更新版本后试试: https://github.com/golang/go/issues/42330

  • 資深大佬 : binbinyouliiii

    Go 不是带 GC 的吗?没触发 GC ?

  • 資深大佬 : xkeyideal

    go 1.15 版本的内存回收机制导致的,升级至 1.16 版本试试吧
    另外 defer 的问题,每次 new http.Client 的方式也是错的

  • 資深大佬 : jitongxi

    是这样的, 只要你用了 go 的标准 http 库,内存就会一直多 5m 左右,应该有很多初始化的上下文, 估计要看源码才知道

  • 資深大佬 : cheng6563

    @binbinyouliiii GC 了也不会把内存还给操作系统,1.16 之前尤其如此

  • 資深大佬 : DollarKiller

    是长链接问题,你看下源码就知道了, 外婆卖瓜下 github.com/dollarkillerx/urllib 这个库有效的解决了这个问题

  • 資深大佬 : xx6412223

    开一夜试试。我感觉问题不大

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具