Golang register finalizer for underlying slice data

409 Views Asked by At

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

0

There are 0 best solutions below