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

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

  •  
  •   bunny189 · 2024-08-30 20:13:06 +08:00 via iPhone · 6378 次点击
    这是一个创建于 371 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    完美~

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

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