亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么永遠不會調用終結器?

為什么永遠不會調用終結器?

Go
泛舟湖上清波郎朗 2023-04-24 16:50:59
var p = &sync.Pool{    New: func() interface{} {        return &serveconn{}    },}func newServeConn() *serveconn {    sc := p.Get().(*serveconn)    runtime.SetFinalizer(sc, (*serveconn).finalize)    fmt.Println(sc, "SetFinalizer")    return sc}func (sc *serveconn) finalize() {    fmt.Println(sc, "finalize")    *sc = serveconn{}    runtime.SetFinalizer(sc, nil)    p.Put(sc)}上面的代碼嘗試重用 object by SetFinalizer,但調試后我發現 finalizer 從未被調用,為什么?更新這可能是相關的: https: //github.com/golang/go/issues/2368
查看完整描述

1 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

上面的代碼嘗試重用 object by SetFinalizer,但調試后我發現 finalizer 從未被調用,為什么?

僅當 GC 將對象標記為未使用時才會調用終結器,然后在 GC 周期結束時嘗試清掃(釋放)。

作為必然結果,如果在程序運行期間從未執行 GC 循環,則可能永遠不會調用您設置的終結器。

以防萬一您可能對 Go 的 GC 持有錯誤的假設,可能值得注意的是 Go 不對值使用引用計數;相反,它使用與程序并行工作的 GC,并且它工作的會話定期發生,并由某些參數觸發,例如分配產生的堆壓力。

關于終結器的一些注釋:

  • 當程序終止時,不會強制運行 GC。

    這樣做的一個必然結果是終結器根本不能保證運行。

  • 如果 GC 在將要釋放的對象上找到終結器,它會調用終結器但不會釋放該對象。

    對象本身只會在下一個 GC 周期被釋放——浪費內存。

總而言之,您看起來像是在嘗試實現析構函數。請不要:讓你的對象實現被調用的那種標準方法,Close并在你的類型的契約中聲明程序員在完成對象時需要調用它。當程序員無論如何都想調用這樣的方法時,他們會使用defer.

請注意,這種方法非常適用于 Go stdlib 中的所有類型,這些類型包裝了操作系統提供的資源——文件和套接字描述符。所以沒有必要假裝你的類型有什么不同。

要記住的另一件有用的事情是,Go 被明確設計為嚴肅、簡潔、沒有魔法、面對面的語言,而您只是想為其添加魔法。請不要,那些喜歡解密魔法層的人會使用Scala不同的語言進行編程。


查看完整回答
反對 回復 2023-04-24
  • 1 回答
  • 0 關注
  • 159 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號