dongzice4895 2018-09-01 07:51
浏览 68
已采纳

gc如何处理切片内存回收

var a = [...]int{1,2,3,4,5,6}
s1 := a[2:4:5]

Suppose s1 goes out of scope later than a. How does gc know to reclaim the memory of s1's underlying array a?

Consider the runtime representation of s1, spec

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

The GC doesn't even know about the beginning of a.

  • 写回答

1条回答 默认 最新

  • douwen9540 2018-09-01 11:12
    关注

    Go uses mark-and-sweep collector as it's present implementation.

    As per the algorithm, there will be one root object, and the rest is tree like structure, in case of multi-core machines gc runs along with the program on one core.

    gc will traverse the tree and when something is not reachable it, considers it as free.

    Go objects also have metadata for objects as stated in this post.

    An excerpt:

    We needed to have some information about the objects since we didn't have headers. Mark bits are kept on the side and used for marking as well as allocation. Each word has 2 bits associated with it to tell you if it was a scalar or a pointer inside that word. It also encoded whether there were more pointers in the object so we could stop scanning objects sooner than later.

    The reason go's slices (slice header) were structures instead of pointer to structures is documented by russ cox in this page under slice section.

    This is an excerpt:

    Go originally represented a slice as a pointer to the structure(slice header) , but doing so meant that every slice operation allocated a new memory object. Even with a fast allocator, that creates a lot of unnecessary work for the garbage collector, and we found that, as was the case with strings, programs avoided slicing operations in favor of passing explicit indices. Removing the indirection and the allocation made slices cheap enough to avoid passing explicit indices in most cases.

    The size(length) of an array is part of its type. The types [1]int and [2]int are distinct.

    One thing to remember is go is value oriented language, instead of storing pointers, they store direct values.

    [3]int, arrays are values in go, so if you pass an array, it copies the whole array. [3]int this is a value (one as a whole).

    When one does a[1] you are accessing part of the value.

    SliceHeader Data field says consider this as base point of array, instead of a[0]

    As far as my knowledge is considered:

    When one requests for a[4],

    a[0]+(sizeof(type)*4)
    

    is calculated.

    Now if you are accessing something in through slice s = a[2:4], and if one requests for s[1], what one was requesting is,

    a[2]+sizeof(type)*1
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度