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

请问这段 Go 代码会内存泄漏吗?

  •  
  •   petelin · 13 天前 · 1478 次点击
    
    import (
       "fmt"
       "runtime"
       "strconv"
       "time"
    )
    
    func do() {
       max := 2100000
       item := 11511
       var a []int
       for range make([]struct{}, max) {
          a = append(a, item)
       }
       var sitem []string
       for range make([]struct{}, max) {
          sitem = append(sitem, strconv.Itoa(item))
       }
       fmt.Println(len(sitem))
       runtime.GC()
    }
    
    func main() {
       for range make([]struct{}, 10) {
          go do()
       }
       time.Sleep(time.Hour)
    }``` 我个逻辑线上的代码简化版,占用内存 1.1G...怎么会这样, 是没有被 GC 掉吗?
    
    13 回复  |  直到 2018-12-08 16:06:26 +08:00
        1
    xujiaja   13 天前
    如果想要立即释放,可以调用 runtime/debug 里的 FreeOSMemory()
        2
    petelin   13 天前
    @xujiaja em...也试了, 内存也没有减少
        3
    Licsber   13 天前
    试了一下, 占用内存从 1000M 在 5 秒左右掉到了 744M 10 秒左右 434M 15 秒左右 239M 20 秒就只有 99M 了 最后稳定在 3M 内存占用 没发现 gc 失败啊.. go 最新版本 1.11.2 goland 也是最新版本 2018.3
        4
    petelin   13 天前
    @Licsber 请问你用什么工具看内存的? 我对 htop 是不是有点误解...
        5
    petelin   13 天前
    @Licsber 我在 mac 上测试的, 好像是因为 thread 没有退出.
    Sampling process 19768 for 3 seconds with 1 millisecond of run time between samples
    Sampling completed, processing symbols...
    Analysis of sampling ___go_build_add_go (pid 19768) every 1 millisecond
    Process: ___go_build_add_go [19768]
    Path: /private/var/folders/wd/vt73dmmj5y38hft8kg5l1wgm0000gq/T/___go_build_add_go
    Load Address: 0x1000000
    Identifier: ___go_build_add_go
    Version: ???
    Code Type: X86-64
    Parent Process: goland [14064]

    Date/Time: 2018-12-06 21:33:47.174 +0800
    Launch Time: 2018-12-06 21:33:00.224 +0800
    OS Version: Mac OS X 10.13.6 (17G3025)
    Report Version: 7
    Analysis Tool: /usr/bin/sample

    Physical footprint: 1.2G
    Physical footprint (peak): 1.2G
    ----

    Call graph:
    2580 Thread_15197711 DispatchQueue_1: com.apple.main-thread (serial)
    + 2580 runtime.asmcgocall (in ___go_build_add_go) + 112 [0x1050da0]
    + 2580 runtime.pthread_cond_timedwait_relative_np_trampoline (in ___go_build_add_go) + 20 [0x1053204]
    + 2580 _pthread_cond_wait (in libsystem_pthread.dylib) + 789 [0x7fff5779a5c2]
    + 2580 __psynch_cvwait (in libsystem_kernel.dylib) + 10 [0x7fff575d1a16]
    2580 Thread_15197713
    + 2580 thread_start (in libsystem_pthread.dylib) + 13 [0x7fff57798bf9]
    + 2580 _pthread_start (in libsystem_pthread.dylib) + 377 [0x7fff5779950d]
    + 2580 runtime.mstart_stub (in ___go_build_add_go) + 46 [0x10530ce]
    + 2580 runtime.mstart (in ___go_build_add_go) + 102 [0x102b9d6]
    + 2580 runtime.mstart1 (in ___go_build_add_go) + 230 [0x102bad6]
    + 2580 runtime.sysmon (in ___go_build_add_go) + 371 [0x10330b3]
    + 2580 runtime.notetsleep (in ___go_build_add_go) + 105 [0x1009499]
    + 2580 runtime.notetsleep_internal (in ___go_build_add_go) + 269 [0x10092cd]
    + 2580 runtime.semasleep (in ___go_build_add_go) + 271 [0x1024e3f]
    + 2580 runtime.pthread_cond_timedwait_relative_np (in ___go_build_add_go) + 81 [0x1043301]
    + 2580 runtime.asmcgocall (in ___go_build_add_go) + 173 [0x1050ddd]
    + 2580 runtime.pthread_cond_timedwait_relative_np_trampoline (in ___go_build_add_go) + 20 [0x1053204]
    + 2580 _pthread_cond_wait (in libsystem_pthread.dylib) + 789 [0x7fff5779a5c2]
    + 2580 __psynch_cvwait (in libsystem_kernel.dylib) + 10 [0x7fff575d1a16]
    2580 Thread_15197714
    + 2580 runtime.mcall (in ___go_build_add_go) + 91 [0x104f52b]
    + 2580 runtime.goexit0 (in ___go_build_add_go) + 498 [0x102f552]
    + 2580 runtime.schedule (in ___go_build_add_go) + 314 [0x102eb6a]
    + 2580 runtime.findrunnable (in ___go_build_add_go) + 1244 [0x102e05c]
    + 2580 runtime.stopm (in ___go_build_add_go) + 227 [0x102cee3]
    + 2580 runtime.notesleep (in ___go_build_add_go) + 227 [0x1009163]
    + 2580 runtime.semasleep (in ___go_build_add_go) + 133 [0x1024db5]
    + 2580 runtime.pthread_cond_wait (in ___go_build_add_go) + 81 [0x1043291]
    + 2580 runtime.asmcgocall (in ___go_build_add_go) + 173 [0x1050ddd]
    + 2580 runtime.pthread_cond_wait_trampoline (in ___go_build_add_go) + 16 [0x10531e0]
    + 2580 _pthread_cond_wait (in libsystem_pthread.dylib) + 732 [0x7fff5779a589]
    + 2580 __psynch_cvwait (in libsystem_kernel.dylib) + 10 [0x7fff575d1a16]
    .... 一共重复了 10 个 thread. 我在研究一下
        6
    petelin   13 天前
    @petelin 巧合, 里面的内容和我的业务逻辑没关系...
        7
    xujiaja   13 天前   ♥ 1
    我在 main 函数里面的循环 sleep,一秒创建一个协程的情况下,内存基本上稳定在第一次协程分配的值。应该是主程序 sleep 的情况下,并没有其他的对象要分配,所以就不回收了。
        8
    petelin   12 天前
    @xujiaja 你是对的, 我把最后那个 sleep 一个小时, 改成了 for{}, 就可以回收了. 谢谢
        9
    HanMeiM   12 天前
    - -我也基本上维持在 1 - 1.1g 左右的内存占用
        10
    Vegetable   12 天前
    测了一下你的代码,稳定一会儿 1.2g,后来忘记看了,过了十来分钟看一下 50M 了.
        11
    Licsber   12 天前
    @petelin 就是 htop 啊 稍微过一会就能看到内存急剧下降 2018 款 MacBookpro 系统是最新的 Mojave 和我的环境应该没啥问题吧..
        12
    petelin   11 天前 via iPhone
    @Licsber 感觉和环境真有关系,你确定一模一样?包括 time.sleep ?
        13
    Licsber   11 天前
    @petelin 对的 我一行代码都没改 直接 go build 运行的
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2146 人在线   最高记录 4019   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 34ms · UTC 15:35 · PVG 23:35 · LAX 07:35 · JFK 10:35
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1