Reputation: 565
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.
Upvotes: 3
Views: 668
Reputation: 1571
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
Upvotes: 1