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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f299fa55-9046-45bd-ba5c-0904bd6c3e0an%40googlegroups.com.

Reply via email to