On Tue, May 8, 2018 at 12:51 PM,  <klo...@gmail.com> wrote:
>
> On Tuesday, May 1, 2018 at 10:15:08 PM UTC+2, Ian Lance Taylor wrote:
>>
>> On Tue, May 1, 2018 at 1:00 PM,  <time...@gmail.com> wrote:
>> >
>> > I looked at the source but can't understand it well enough.
>> >
>> > If I allocate a [1000]byte, or a []byte, I understand the GC will need
>> > to
>> > mark the slice/array itself for collection. However, does the GC mark
>> > all
>> > the bytes within, and does the marking phase attempt to follow all the
>> > items?
>>
>> A [1000]byte value holds no pointers, so the GC marks that value once
>> and does not look inside it.
>>
>> A []byte holds a single pointer, to the backing array, and the backing
>> array holds no pointers, so the GC marks the []byte and the backing
>> array, and then stops.
>>
>>
>
> Interesting. And what happens in this case:
>
>  type Foo struct {
>   s string
> }
>
> func makeFoo() *Foo {
>   buf := make([]byte,16)
>   foo := (*Foo)(unsafe.Pointer(&buf))
>   foo.s = "Hello World!"
>   return foo
> }
>
> If I understand you correctly, the GC would consider the string "Hello
> World!" to be collectable, because its only pointer is in memory that should
> not hold pointers. Or does the assignment of foo.s add some mark to the
> memory block that it now may contain pointers?

That program is not one of the valid unsafe.Pointer patterns
documented at https://golang.org/pkg/unsafe, so it is invalid.  As you
say, the string "Hello World!" could be collected by the GC.  With the
current implementations the string is likely to be in read-only memory
so it would not be collected, but of course future implementations may
act differently.  In the current implementations the assignment to
foo.s does not add any marking to the memory block.  It would remain
marked as not containing any pointers.

> If I changed buf to
>
> buf := make([]unsafe.Pointer,16)
>
> would that make things work? Now the GC knows that buf may contain pointers
> and if I understand correctly it doesn't need to know the type of pointer.

That would still be invalid according to the unsafe.Pointer docs.  The
results would be different.  The representation of a string is both a
pointer and a length.  With this change, you would be storing the
length into a field marked as containing a pointer.  In other words,
you would have an invalid pointer value.  The most likely result would
be a crash when the garbage collector tried to mark the memory to
which that pointer points.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to