V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
bunny189
V2EX  ›  Go 编程语言

Go 初学者,有没有老哥能告诉我在写代码的时候应该如何避免内存泄漏的问题

  •  
  •   bunny189 · 84 天前 via iPhone · 4761 次点击
    这是一个创建于 84 天前的主题,其中的信息可能已经有所发展或是发生改变。

    万分感谢! 并不是想 100%避免,只是希望少点蠢代码……

    39 条回复    2024-09-02 12:51:54 +08:00
    bunny189
        1
    bunny189  
    OP
       84 天前 via iPhone
    目前已经写完一个项目,即将上服务器(有固定人流量),所以有点紧张,想临上线前看看有没有出一些愚蠢低级的错误()
    DefoliationM
        2
    DefoliationM  
       84 天前 via Android
    go 有 gc ,何来内存泄漏一说。逻辑问题你只能写代码时看清楚吧。
    GeekGao
        3
    GeekGao  
       84 天前
    GeekGao
        4
    GeekGao  
       84 天前   ❤️ 2
    ashin
        5
    ashin  
       84 天前   ❤️ 3
    定时重启 /狗头
    bunny189
        6
    bunny189  
    OP
       84 天前 via iPhone
    @GeekGao 谢谢好心人,我对照着自查一下❤️!
    @ashin 难道他真是天才??!
    virusdefender
        7
    virusdefender  
       84 天前
    线上默认把 pprof 打开,别到时候发现泄露了还得重新编译
    Trim21
        8
    Trim21  
       84 天前   ❤️ 1
    你不用 unsafe ,不用 arena 之类的东西的话一般不会有内存泄漏。一般泄漏的都是 fd 、socket 、goroutine 之类的东西。
    James369
        9
    James369  
       84 天前
    写完让 ChatGpt 检查一下
    mightybruce
        10
    mightybruce  
       84 天前
    一般使用 go 的一些静态检查分析工具,过滤掉大多数问题代码,go vet 工具
    tuiL2
        11
    tuiL2  
       84 天前
    golang 能写出内存泄露,应该也挺不容易的吧
    maigebaoer
        12
    maigebaoer  
       84 天前 via Android
    一般泄露的都是全局资源,小项目挺难遇到的
    bruce0
        13
    bruce0  
       84 天前
    我唯一遇到过一次的 go 内存泄漏是 goroutine 工作完成后没有结束(被阻塞了) 然后相关的资源都没有释放, 别的基本遇不到内存泄漏
    povsister
        14
    povsister  
       84 天前
    go 一般是资源泄露,用 goroutine 前想想这个东西的生命周期就能避免大多数情况。
    donaldturinglee
        15
    donaldturinglee  
       84 天前
    go 的垃圾回收还是很健壮的,非常规问题不考虑内存泄漏
    Ipsum
        16
    Ipsum  
       84 天前
    别再 for 里用 time.after
    higker
        17
    higker  
       84 天前
    建议你使用 Java21 版本 和 graalvm.org 这种多语言虚拟机,可以管理多语言跑多语言,管理内存分配。
    securityCoding
        18
    securityCoding  
       84 天前 via Android
    go lint 扫一下,profile 看看内存和协程数量
    kneo
        19
    kneo  
       84 天前
    你在这发有啥用?赶紧上线啊。让用户帮你测试。
    lingo
        20
    lingo  
       84 天前
    我 go 项目有用到 cgo ,没想到用的那个 cgo 库居然自带内存泄露。。。
    kaf
        21
    kaf  
       84 天前
    一般不是搞一堆 goroutin 很难触发,注意使用 defer ,定时重启,go 原生程序重启真的很快
    crackidz
        22
    crackidz  
       84 天前
    Go 不乱搞一般没有内存泄露,资源泄露排查一下打开的东西是不是没关
    dyllen
        23
    dyllen  
       84 天前
    @Ipsum 这个问题在 1.23 版已经解决了,不会又问题了。
    mainjzb
        24
    mainjzb  
       84 天前
    https://github.com/UltimateYhq/100-GO-mistakes

    看这种常规错误避免,剩下 gc 帮你兜底应该问题不大。
    testcgd
        25
    testcgd  
       84 天前 via Android
    1. checklist 各种,这里手打太麻烦了,你可以直接上网搜一下,主要还是协程泄露比较多,全局变量的泄露很少的,避免协程被 chan 阻塞,基本就可以了
    2. 建立优雅重启的方案,如果你的程序一小时可以无损的重启一次,加上监控,内存大了起个新的实来接管流量,这个可以把影响降到最低
    3.其实比起内存泄露,你更应该担心的是 panic 导致的进程异常退出,没处理好容易有各种的脏数据
    NewYear
        26
    NewYear  
       84 天前
    懂了,先搞一个启动器,接管 tcp/udp ,启动主程序,并定时启动新的,关掉旧的……
    客户端连接的时候映射到新启动的,旧的自然就不需要了。

    完美~

    等等,这不就是集群么
    oneisall8955
        27
    oneisall8955  
       84 天前
    没用过 go ,真的有企业采用定时重启方案?震惊
    testcgd
        28
    testcgd  
       84 天前 via Android
    @oneisall8955 企业不是定时重启,而是是版本迭代加 pgo 优化编译 人工狗头
    nyxsonsleep
        29
    nyxsonsleep  
       84 天前
    @oneisall8955 #26 同样震惊
    GeekGao
        30
    GeekGao  
       84 天前
    @oneisall8955 有,以前听过一个同事分享过,某大安全厂商旗下搜索引擎有个服务,第三方库搞不定内存泄露问题,就用重启大法了。
    bunny189
        31
    bunny189  
    OP
       83 天前
    @mainjzb 好!谢谢老哥,我看看
    @testcgd 恩恩,想问问大佬,如果协程只是执行一个函数(比如:更新数据库记录)这种不需要 channel 通信的,是不是基本不会有阻塞的问题?
    testcgd
        32
    testcgd  
       83 天前 via Android
    @bunny189 基本不会,不过也要看实现,有时候不一定是阻塞,qps 高的时候慢查询也会有问题的,上线再说,有问题重启就好
    bunny189
        33
    bunny189  
    OP
       83 天前 via iPhone
    @testcgd 明白了,谢谢您!
    edcopclub
        34
    edcopclub  
       82 天前 via Android
    一般只需要注意 goroutine 结束不了的情况,比如一直阻塞。
    picone
        35
    picone  
       82 天前
    - 统计 gorouting 使用场景并上报 metric 。如果是 HTTP 服务可以接口路径作为一个 label ,这样即使发生 goroutine 泄露也能快速定位是哪个场景的问题。
    - 少修改全局变量。全局变量修改会涉及竞态问题也麻烦
    - pprof 可以不开启,但是可以做个内部调用接口开启,在发生内存泄漏的时候开启然后收集即可,这样对性能影响也不大。
    snowlyg
        36
    snowlyg  
       82 天前
    重启方案 当然是最简单实用的方案啊
    Jinnrry
        37
    Jinnrry  
       82 天前
    线上默认把 pprof 打开就行了,我写了四五年 go 了,还从来没遇到过内存泄露。

    一般 fd 、goroutine 之类的泄露比较多。
    Jinnrry
        38
    Jinnrry  
       82 天前
    @GeekGao #30 我当年也遇到过,某个第三方库内存泄露了,一时半会搞不到,恰好又遇到双十一活动,上报 cto 后,协调了几十台几 T 内存的服务器过来硬扛了半个月,每天不同机器再轮流重启
    GeekGao
        39
    GeekGao  
       82 天前
    @Jinnrry 2333 能解决业务问题就好。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 09:33 · PVG 17:33 · LAX 01:33 · JFK 04:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.