成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 1.24 中的弱指針包 weak 使用

開發 后端
簡而言之,弱指針不會增加對象的引用計數。當一個對象只被弱指針引用時,垃圾回收器就可以釋放它。因此,在嘗試使用弱指針的值之前,應檢查它是否為 nil。

在 Go 語言中,“弱指針”指的是不會阻止垃圾回收器(GC)回收目標對象的引用。

當一個對象只剩弱指針指向它,而沒有任何強引用時,GC 仍會把該對象當作不可達對象并回收;隨后,所有指向它的弱指針會自動變為 nil。

簡而言之,弱指針不會增加對象的引用計數。當一個對象只被弱指針引用時,垃圾回收器就可以釋放它。因此,在嘗試使用弱指針的值之前,應檢查它是否為 nil。

Go 1.24 中的 weak 包

Go 1.24 新增 weak 包,提供了創建和使用弱指針的簡潔 API。

import "weak"

type MyStruct struct {
    Data string
}

func main() {
    obj := &MyStruct{Data: "example"}
    wp := weak.Make(obj) // 創建弱指針
    val := wp.Value()    // 獲取強引用或 nil
    if val != nil {
        fmt.Println(val.Data)
    } else {
        fmt.Println("對象已被垃圾回收")
    }
}

在以上示例中,weak.Make(obj) 創建了指向 obj 的弱指針。調用 wp.Value() 時,如果對象仍存活則返回強引用,否則返回 nil。

測試弱指針:

import (
    "fmt"
    "runtime"
    "weak"
)

type MyStruct struct {
    Data string
}

func main() {
    obj := &MyStruct{Data: "test"}
    wp := weak.Make(obj)
    obj = nil // 移除強引用
    runtime.GC()
    if wp.Value() == nil {
        fmt.Println("對象已被垃圾回收")
    } else {
        fmt.Println("對象仍然存活")
    }
}

通過將強引用 obj 置為 nil 并主動觸發 GC,可觀察到弱指針在對象被回收后返回 nil 的行為。

弱指針”與“強引用”的區別

特性

強引用 (*T)

弱引用 (weak.Pointer[T])

影響 GC

會保持對象存活

不會保持對象存活

空值

nil

nil

(目標被回收或從未賦值)

訪問方式

直接解引用

先調用 Value()

示例 1: 弱指針做臨時緩存

使用弱指針的一個典型場景是在緩存中存儲條目,同時不阻止它們被 GC 回收。

package main

import (
    "fmt"
    "runtime"
    "sync"
    "weak"
)

type User struct {
    Name string
}

var cache sync.Map // map[int]weak.Pointer[*User]

func GetUser(id int) *User {
    // ① 先從緩存里取
    if wp, ok := cache.Load(id); ok {
        if u := wp.(weak.Pointer[User]).Value(); u != nil {
            fmt.Println("cache hit")
            return u
        }
    }

    // ② 真正加載(這里直接構造)
    u := &User{Name: fmt.Sprintf("user-%d", id)}
    cache.Store(id, weak.Make(u))
    fmt.Println("load from DB")
    return u
}

func main() {
    u := GetUser(1) // load from DB
    fmt.Println(u.Name)

    runtime.GC() // 即使立刻 GC,因 main 持有強引用,User 仍在

    u = nil      // 釋放最后一個強引用
    runtime.GC() // 觸發 GC,User 可能被回收

    _ = GetUser(1) // 如被回收,會再次 load from DB
}

在該緩存實現中,條目以弱指針形式存儲。如果對象沒有其他強引用,GC 可以將其回收;下次調用 GetUser 時,數據會被重新加載。

運行上述代碼,輸出如下:

$ go run cache.go 
load from DB
user-1
load from DB

為什么要使用弱指針?

常見場景包括:

  • 緩存:在不強制對象常駐內存的前提下存儲它們,如果其他地方不再使用,對象就能被回收;
  • 觀察者模式:保存對觀察者的引用,同時不阻止它們被 GC 回收;
  • 規范化(Canonicalization):確保同一對象只有一個實例,并且在不再使用時可被回收;
  • 依賴關系圖:在樹或圖等結構中避免形成引用環。

弱指針使用注意事項

  • 隨時檢查 nil:對象可能在任意 GC 周期后被回收,Value() 結果不可緩存。
  • 避免循環依賴:不要讓弱指針中的對象重新持有創建它的容器,否則仍會形成強引用鏈。
  • 性能權衡:訪問弱指針需要額外調用,且頻繁從 nil 狀態恢復對象會導致抖動。

示例 2:強指針的普通使用

package main  

import (  
 "fmt"  
 "runtime"  
)  

type Session struct {  
 ID string  
}  

func main() {  
 s := new(Session) // 與 &Session{} 等價  
 s.ID = "abc123"  

 fmt.Println("strong ref alive:", s.ID)  

 s = nil           // 取消最后一個強引用  
 runtime.GC()      // 嘗試觸發 GC(僅演示,實際時機由運行時決定)  

 fmt.Println("done")  
}

這里的 s 就是強指針,只要它仍然可達,Session 對象就絕不會被 GC 回收。

強指針指向的對象何時被 GC?

(1) 可達性判定:Go 使用標記-清除式 GC。一次 GC 周期開始時,運行時會從根對象(棧、全局變量、當前寄存器等)向外遍歷所有強引用。

  • 能通過強引用鏈到達的對象稱為可達 (reachable),一定存活;
  • 其余對象被標記為不可達 (unreachable),在清掃階段釋放。

(2) 不存在“引用計數”:只有“是否從根可達”這一條件;變量數目多少、值是否相等都不影響回收;

(3) 時間點不確定:GC 周期由調度器自動觸發,開發者只能調用 runtime.GC() 進行“建議”式觸發,不能保證立即回收;

(4) 變量本身也會被 GC:若強指針變量 s 位于堆上且其所在結構不再可達,那么 s 本身也會被 GC;棧變量則隨函數返回被回收。

總結一句:強指針保證可達對象在任意 GC 周期都處于“存活集合”中;一旦最后的強引用鏈斷開,對象就會在下一個 GC 周期被自動釋放。

責任編輯:趙寧寧 來源: 孔令飛
相關推薦

2024-10-09 08:54:31

2023-10-26 11:19:21

指針Go

2015-07-08 16:28:23

weak生命周期

2025-05-06 08:00:35

2015-03-16 10:33:14

Swift指針

2015-01-21 16:25:29

Swift指針

2024-09-03 08:49:01

2025-05-07 08:55:14

GoMap存儲

2021-09-27 22:49:13

GoC 指針

2021-04-13 07:58:42

Go語言函數

2022-01-10 13:01:32

指針Struct內存

2025-03-07 09:12:28

2021-10-26 13:18:52

Go底層函數

2025-01-06 09:18:04

2025-05-26 08:15:00

Go開發指針

2022-08-08 08:31:55

Go 語言閉包匿名函數

2022-08-08 06:50:06

Go語言閉包

2025-05-26 10:10:00

Go開發testing

2019-12-10 13:55:10

Go指針存儲

2025-02-08 11:00:33

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国内精品 | 青青草这里只有精品 | 精品国产一区二区三区免费 | 国产一区二区三区四区五区加勒比 | 黄网站涩免费蜜桃网站 | 国产成人久久av免费高清密臂 | 免费国产视频 | 国产精品久久av | 日韩av啪啪网站大全免费观看 | 国产在线观 | 一本色道精品久久一区二区三区 | 一区二区三区视频在线观看 | 中文字幕亚洲欧美日韩在线不卡 | 伊人久久综合 | 99福利视频| 中文字幕第一页在线 | 国产精品178页 | 免费精品| 国产成人99久久亚洲综合精品 | 国产午夜精品久久久 | 亚洲男人天堂 | 亚洲精品电影 | 久久9视频 | 欧美极品一区二区 | 国产乱码精品一区二区三区五月婷 | 国产精品第2页 | 国产精品久久精品 | 国产一区二区三区 | 国产精品一二三区 | 色综合久久久久 | 日韩精品一区二区三区在线观看 | 欧美专区在线观看 | 一区二区三区视频在线免费观看 | 五月天天丁香婷婷在线中 | 成人免费淫片aa视频免费 | 国产精品久久久久一区二区三区 | 亚洲成人在线网 | 欧美性jizz18性欧美 | 亚洲一区不卡 | www.久久 | 精品国产欧美一区二区 |