My goal is to get a callback whenever the underlying data of a buffer isn't referenced anywhere and should therefore be eligible for GC. I'm trying to implement this functionality by registering a finalizer on top of a buffer.
In the code snippet below, for every iteration, I'm creating some buffer and for each created buffer, I'm registering a finalizer. The buffer is appended to an array of buffers.
The problem in that code, is that if the callee (main function in that case) calls * on the return value of makeSlice, the finalizer will get called even though the underlying data will not get GCed.
package main
import (
"fmt"
"runtime"
"time"
)
func finalizer(_ *[]byte) {
fmt.Println("finalize is called")
}
// makeSlice generates a buffer and register a finalizer.
func makeSlice() *[]byte {
buffer := []byte(fmt.Sprintf("some info"))
runtime.SetFinalizer(&buffer, finalizer)
return &buffer
}
func main() {
var buffers [][]byte
for i := 0; i < 10000; i++ {
buffers = append(buffers, *makeSlice())
}
// run some GC and wait a little.
runtime.GC()
time.Sleep(1 * time.Second)
// do something with the buffers so that they don't get GC by the previous call
var m byte
for _, buffer := range buffers {
if (buffer)[0] > m {
m = (buffer)[0]
}
}
fmt.Println(m)
}
I'm wondering if there is a way to get a callback when the underlying data of the buffer is to get GCed
Thanks