slice 垃圾回收

windy_ · 2018-07-12 10:15:16 · 1729 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-07-12 10:15:16 的主题,其中的信息可能已经有所发展或是发生改变。

假如我有一个slice,然后其中若干个元素地址被引用,那么其他的元素会被垃圾回收吗

ss := []string{"1", "2", "3", "4"}
ref := &ss[2]

例如这样的一个操作,gc时ss会被垃圾回收吗


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1729 次点击  
加入收藏 微博
6 回复  |  直到 2018-08-27 10:05:46
linkerlin
linkerlin · #1 · 7年之前

方向,Go的GC很智能的.

sheepbao
sheepbao · #2 · 7年之前

不会,ss底层数组被引用,整个数组都不会被释放

windy_
windy_ · #3 · 7年之前
sheepbaosheepbao #2 回复

不会,ss底层数组被引用,整个数组都不会被释放

我之前也是这样想的,但是仔细想想,ss本身是不可达的,程序运行到后面,ss本身是没有被引用的,所有有点疑惑

sheepbao
sheepbao · #4 · 7年之前
windy_windy_ #3 回复

#2楼 @sheepbao 我之前也是这样想的,但是仔细想想,ss本身是不可达的,程序运行到后面,ss本身是没有被引用的,所有有点疑惑

https://golang.google.cn/pkg/reflect/#SliceHeader

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

这是slice的内部结构,我的理解是slice的data指针只有一个,表示底层数组,在gc的时候如果检测到data有被引用就不会被回收,gc最左管理到这个data数组,他不会管到数组的某个元素,不过你的例子是string slice,对于string感觉比较特殊,可以写个例子测试一下,开启gctrace看看结果

sheepbao
sheepbao · #5 · 7年之前
package gc_test

import (
    "log"
    "runtime"
    "runtime/debug"
    "strconv"
    "testing"
    "time"
)

func TestGC(t *testing.T) {
    ss := make([]string, 100<<20)
    for i := range ss {
        ss[i] = strconv.Itoa(i)
    }
    log.Println("gc before1")
    time.Sleep(2 * time.Second)
    log.Println("gc before2")
    runtime.GC()
    debug.FreeOSMemory()
    log.Println("gc after1")
    ref := &ss[2]
    runtime.GC()
    debug.FreeOSMemory()
    log.Println("gc after2")

    time.Sleep(5 * time.Second)

    log.Printf("ref: %p", ref)
}

/*
GODEBUG=gctrace=1 go test -v -count=1 -timeout 30s  -run ^TestGC$
gc 1 @0.034s 0%: 0.029+0.85+0.029 ms clock, 0.11+0.27/0.64/1.5+0.11 ms cpu, 4->4->0 MB, 5 MB goal, 4 P
gc 2 @0.057s 0%: 0.006+0.48+0.025 ms clock, 0.024+0.18/0.40/0.65+0.10 ms cpu, 4->4->0 MB, 5 MB goal, 4 P
gc 3 @0.075s 0%: 0.005+0.63+0.043 ms clock, 0.023+0.21/0.56/0.55+0.17 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
gc 4 @0.115s 0%: 0.031+1.0+0.097 ms clock, 0.12+0.23/0.73/1.4+0.39 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
gc 5 @0.120s 0%: 0.020+1.5+0.10 ms clock, 0.083+0.19/1.3/0.40+0.42 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
gc 6 @0.127s 0%: 0.016+1.4+0.028 ms clock, 0.064+0.71/0.66/2.3+0.11 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
gc 7 @0.133s 0%: 0.036+1.1+0.070 ms clock, 0.14+0.51/1.0/0.41+0.28 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
gc 8 @0.137s 0%: 0.004+0.84+0.073 ms clock, 0.019+0.31/0.77/0.69+0.29 ms cpu, 4->4->1 MB, 5 MB goal, 4 P
# _/Users/bao/program/go/opensource/fastip-research/src/research/gc_test
gc 1 @0.005s 0%: 0.015+4.7+0.042 ms clock, 0.062+1.4/4.1/2.9+0.16 ms cpu, 4->4->3 MB, 5 MB goal, 4 P
gc 2 @0.015s 0%: 0.025+3.0+0.037 ms clock, 0.10+1.2/2.9/2.5+0.15 ms cpu, 6->6->5 MB, 7 MB goal, 4 P
# _/Users/bao/program/go/opensource/fastip-research/src/research/gc (testmain)
gc 1 @0.006s 0%: 0.014+4.4+0.087 ms clock, 0.058+0.27/2.4/3.6+0.34 ms cpu, 4->4->3 MB, 5 MB goal, 4 P
# _/Users/bao/program/go/opensource/fastip-research/src/research/gc_test
gc 1 @0.008s 0%: 0.016+0.84+0.054 ms clock, 0.065+0/0.17/0.70+0.21 ms cpu, 4->4->2 MB, 5 MB goal, 4 P
gc 2 @0.009s 0%: 0.004+1.0+0.089 ms clock, 0.019+0/0.17/0.94+0.35 ms cpu, 4->4->3 MB, 5 MB goal, 4 P
# _/Users/bao/program/go/opensource/fastip-research/src/research/gc (testmain)
gc 1 @0.001s 0%: 0.008+4.3+0.16 ms clock, 0.035+0.12/4.0/0.55+0.64 ms cpu, 4->5->4 MB, 5 MB goal, 4 P
gc 2 @0.014s 0%: 0.006+2.2+0.074 ms clock, 0.024+0.40/2.1/2.0+0.29 ms cpu, 7->8->8 MB, 9 MB goal, 4 P
gc 3 @0.033s 0%: 0.007+5.3+0.036 ms clock, 0.029+0.13/5.2/7.3+0.14 ms cpu, 14->15->14 MB, 16 MB goal, 4 P
gc 4 @0.064s 0%: 0.006+8.4+0.071 ms clock, 0.024+0.063/8.1/11+0.28 ms cpu, 26->29->27 MB, 28 MB goal, 4 P
=== RUN   TestGC
gc 1 @0.138s 0%: 0.030+697+0.025 ms clock, 0.12+0.21/697/1332+0.10 ms cpu, 1600->1646->1646 MB, 1601 MB goal, 4 P
gc 2 @0.842s 0%: 0.003+336+0.025 ms clock, 0.012+0.40/336/646+0.10 ms cpu, 1647->1669->1669 MB, 3292 MB goal, 4 P


2018/07/13 16:17:46 gc before1
2018/07/13 16:17:48 gc before2
gc 3 @8.360s 0%: 0.007+1582+0.022 ms clock, 0.031+0/1582/4738+0.090 ms cpu, 2436->2436->2436 MB, 3338 MB goal, 4 P (forced)
gc 4 @9.986s 0%: 0.005+873+0.031 ms clock, 0.022+0/873/2599+0.12 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced)
scvg-1: 0 MB released
scvg-1: inuse: 2437, idle: 0, sys: 2437, released: 0, consumed: 2437 (MB)
2018/07/13 16:17:51 gc after1
gc 5 @10.896s 0%: 0.036+826+0.036 ms clock, 0.14+0/826/2476+0.14 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced)
gc 6 @11.761s 0%: 0.025+823+0.018 ms clock, 0.10+0/823/2468+0.073 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced)
scvg-1: 0 MB released
scvg-1: inuse: 2437, idle: 0, sys: 2437, released: 0, consumed: 2437 (MB)
2018/07/13 16:17:52 gc after2
2018/07/13 16:17:57 ref: 0xc4200ae020
--- PASS: TestGC (17.62s)
PASS


*/

我测试了一下,可以看出确实没有被回收

windy_
windy_ · #6 · 7年之前
sheepbaosheepbao #5 回复

```go package gc_test import ( "log" "runtime" "runtime/debug" "strconv" "testing" "time" ) func TestGC(t *testing.T) { ss := make([]string, 100<<20) for i := range ss { ss[i] = strconv.Itoa(i) } log.Println("gc before1") time.Sleep(2 * time.Second) log.Println("gc before2") runtime.GC() debug.FreeOSMemory() log.Println("gc after1") ref := &ss[2] runtime.GC() debug.FreeOSMemory() log.Println("gc after2") time.Sleep(5 * time.Second) log.Printf("ref: %p", ref) } /* GODEBUG=gctrace=1 go test -v -count=1 -timeout 30s -run ^TestGC$ gc 1 @0.034s 0%: 0.029+0.85+0.029 ms clock, 0.11+0.27/0.64/1.5+0.11 ms cpu, 4->4->0 MB, 5 MB goal, 4 P gc 2 @0.057s 0%: 0.006+0.48+0.025 ms clock, 0.024+0.18/0.40/0.65+0.10 ms cpu, 4->4->0 MB, 5 MB goal, 4 P gc 3 @0.075s 0%: 0.005+0.63+0.043 ms clock, 0.023+0.21/0.56/0.55+0.17 ms cpu, 4->4->1 MB, 5 MB goal, 4 P gc 4 @0.115s 0%: 0.031+1.0+0.097 ms clock, 0.12+0.23/0.73/1.4+0.39 ms cpu, 4->4->1 MB, 5 MB goal, 4 P gc 5 @0.120s 0%: 0.020+1.5+0.10 ms clock, 0.083+0.19/1.3/0.40+0.42 ms cpu, 4->4->1 MB, 5 MB goal, 4 P gc 6 @0.127s 0%: 0.016+1.4+0.028 ms clock, 0.064+0.71/0.66/2.3+0.11 ms cpu, 4->4->1 MB, 5 MB goal, 4 P gc 7 @0.133s 0%: 0.036+1.1+0.070 ms clock, 0.14+0.51/1.0/0.41+0.28 ms cpu, 4->4->1 MB, 5 MB goal, 4 P gc 8 @0.137s 0%: 0.004+0.84+0.073 ms clock, 0.019+0.31/0.77/0.69+0.29 ms cpu, 4->4->1 MB, 5 MB goal, 4 P # _/Users/bao/program/go/opensource/fastip-research/src/research/gc_test gc 1 @0.005s 0%: 0.015+4.7+0.042 ms clock, 0.062+1.4/4.1/2.9+0.16 ms cpu, 4->4->3 MB, 5 MB goal, 4 P gc 2 @0.015s 0%: 0.025+3.0+0.037 ms clock, 0.10+1.2/2.9/2.5+0.15 ms cpu, 6->6->5 MB, 7 MB goal, 4 P # _/Users/bao/program/go/opensource/fastip-research/src/research/gc (testmain) gc 1 @0.006s 0%: 0.014+4.4+0.087 ms clock, 0.058+0.27/2.4/3.6+0.34 ms cpu, 4->4->3 MB, 5 MB goal, 4 P # _/Users/bao/program/go/opensource/fastip-research/src/research/gc_test gc 1 @0.008s 0%: 0.016+0.84+0.054 ms clock, 0.065+0/0.17/0.70+0.21 ms cpu, 4->4->2 MB, 5 MB goal, 4 P gc 2 @0.009s 0%: 0.004+1.0+0.089 ms clock, 0.019+0/0.17/0.94+0.35 ms cpu, 4->4->3 MB, 5 MB goal, 4 P # _/Users/bao/program/go/opensource/fastip-research/src/research/gc (testmain) gc 1 @0.001s 0%: 0.008+4.3+0.16 ms clock, 0.035+0.12/4.0/0.55+0.64 ms cpu, 4->5->4 MB, 5 MB goal, 4 P gc 2 @0.014s 0%: 0.006+2.2+0.074 ms clock, 0.024+0.40/2.1/2.0+0.29 ms cpu, 7->8->8 MB, 9 MB goal, 4 P gc 3 @0.033s 0%: 0.007+5.3+0.036 ms clock, 0.029+0.13/5.2/7.3+0.14 ms cpu, 14->15->14 MB, 16 MB goal, 4 P gc 4 @0.064s 0%: 0.006+8.4+0.071 ms clock, 0.024+0.063/8.1/11+0.28 ms cpu, 26->29->27 MB, 28 MB goal, 4 P === RUN TestGC gc 1 @0.138s 0%: 0.030+697+0.025 ms clock, 0.12+0.21/697/1332+0.10 ms cpu, 1600->1646->1646 MB, 1601 MB goal, 4 P gc 2 @0.842s 0%: 0.003+336+0.025 ms clock, 0.012+0.40/336/646+0.10 ms cpu, 1647->1669->1669 MB, 3292 MB goal, 4 P 2018/07/13 16:17:46 gc before1 2018/07/13 16:17:48 gc before2 gc 3 @8.360s 0%: 0.007+1582+0.022 ms clock, 0.031+0/1582/4738+0.090 ms cpu, 2436->2436->2436 MB, 3338 MB goal, 4 P (forced) gc 4 @9.986s 0%: 0.005+873+0.031 ms clock, 0.022+0/873/2599+0.12 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced) scvg-1: 0 MB released scvg-1: inuse: 2437, idle: 0, sys: 2437, released: 0, consumed: 2437 (MB) 2018/07/13 16:17:51 gc after1 gc 5 @10.896s 0%: 0.036+826+0.036 ms clock, 0.14+0/826/2476+0.14 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced) gc 6 @11.761s 0%: 0.025+823+0.018 ms clock, 0.10+0/823/2468+0.073 ms cpu, 2436->2436->2436 MB, 4873 MB goal, 4 P (forced) scvg-1: 0 MB released scvg-1: inuse: 2437, idle: 0, sys: 2437, released: 0, consumed: 2437 (MB) 2018/07/13 16:17:52 gc after2 2018/07/13 16:17:57 ref: 0xc4200ae020 --- PASS: TestGC (17.62s) PASS */ ``` 我测试了一下,可以看出确实没有被回收

多谢,没有看完整本的go编程,之前没找到查看gc的方法

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传