Hi Elias, thanks for chiming in!

> The Go garbage collector is precise in that it only considers pointers 
when determining memory that can be freed.

Agreed, but it is not as precise on _what_ is a pointer. Specifically, 
which matters?
- the type used upon allocating the memory, or
- the type used upon writing to it.

Because *T or unsafe.Pointer is required upon writing to a memory location 
for it to be marked as a pointer, I came to the conclusion that the type 
upon writing is what matters.

So then both types need to be pointers?

Does that mean there is no way to define a struct-like memory layout 
dynamically, that contains a mix of pointer and non-pointer types, in a way 
that is supported by the GC?
(This is what I'm trying to do.)

On Friday, August 18, 2023 at 3:49:03 PM UTC+2 ma...@eliasnaur.com wrote:

> On Friday, 18 August 2023 at 05:57:38 UTC-6 Tibor Halter wrote:
>
> Thanks Ian!
>
> I have managed to strip it down to its essence, see code below.
>
> *Summary of what I'm doing*
> - reserve memory with make([]byte)
> - get pointer to underlying array
> - cast it to type Num
> - write pointer #2 into it
> - force GC()
> - GC does not follow pointer #2, memory is freed
>
>
> The Go garbage collector is precise in that it only considers pointers 
> when determining memory that can be freed. In your scenario and 
> demonstration program you explicitly store a pointer in a byte slice, 
> effectively making it invisible to the collector.
>  
>
> --
>
>
> package debug
>
> import (
> "testing"
> "runtime"
> "unsafe"
> )
>
> type Num struct {
> numData *uint64
> }
>
> func Test(t *testing.T) {
> n := uint64(123456789)
> numMemSize := 8
> b := make([]byte, numMemSize, numMemSize)
> sliceDataPtr := unsafe.Pointer(unsafe.SliceData(b))
> (*Num)(sliceDataPtr).numData = &n
>
>
> The pointer to &n stored in b here is effectively hidden from the 
> collector.
>  
>
>
> runtime.GC()
>
>
> With no more visible references to (the supposedly heap-allocated) n, it 
> can be freed.
>  
>
>
> act := (*Num)(sliceDataPtr).numData
> if *act != 123456789 {
> t.Fatalf("v[%X]", *act)
> }
> }
>
>
> Elias 
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5051da1c-36de-4699-906c-ff8f50754404n%40googlegroups.com.

Reply via email to