有没有一种方法可以获取使用 runtime.SetFinalizer 注册但尚未运行的终结器的总数?

我们正在考虑将已注册终结器的struct添加到我们的某些产品中,以释放使用malloc分配的内存,并且该对象可能具有相对较高的分配率。如果我们可以监视终结器的数量,以确保它们不会堆积并触发内存不足错误(就像它们倾向于其他垃圾收集器那样),那将是很好的。

(我知道显式取消分配可以避免此问题,但是我们无法更改现有代码,该代码不会调用Close函数或类似的功能。)

最佳答案

您可以通过分别在创建和完成新对象时递增和递减未导出的程序包变量来保持这些对象的计数。

例如:

package main

import (
    "fmt"
    "runtime"
    "sync/atomic"
)

var totalObjects int32

func TotalObjects() int32 {
    return atomic.LoadInt32(&totalObjects)
}

type Object struct {
    p uintptr // C allocated pointer
}

func NewObject() *Object {
    o := &Object{
    }
    // TODO: perform other initializations
    atomic.AddInt32(&totalObjects, 1)
    runtime.SetFinalizer(o, (*Object).finalizer)
    return o
}

func (o *Object) finalizer() {
    atomic.AddInt32(&totalObjects, -1)
    // TODO: perform finalizations
}

func main() {
    fmt.Println("Total objects:", TotalObjects())
    for i := 0; i < 100; i++ {
        _ = NewObject()
        runtime.GC()
    }
    fmt.Println("Total objects:", TotalObjects())
}

https://play.golang.org/p/n35QABBIcj

关于go - 终结器统计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47619192/

10-09 13:52