精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go 弱引用和清理機制優化:從 runtime.AddCleanup 到 weak.Pointer

開發 前端
在 Go 語言的發展歷程中,內存管理一直是個重要話題。我們有垃圾回收器幫助自動回收內存,但在某些場景下,比如需要管理系統資源(文件描述符、內存映射等)時,就需要更精細的控制。

今天給大家分享的兩個在垃圾回收(GC)方面挺有意思的新特性:runtime.AddCleanup清理函數和weak.Pointer弱指針。

這兩個功能不僅解決了傳統 finalizer 的痛點,還為內存管理和性能優化提供了全新的解決方案。一起來學習吧!

背景

在 Go 語言的發展歷程中,內存管理一直是個重要話題。我們有垃圾回收器幫助自動回收內存,但在某些場景下,比如需要管理系統資源(文件描述符、內存映射等)時,就需要更精細的控制。

之前主要依賴runtime.SetFinalizer來實現資源清理,但說實話,finalizer 使用起來真的很容易踩坑。

最大的問題就是對象復活(object resurrection):finalizer 會讓原本應該被回收的對象"復活",至少需要兩次 GC 周期才能真正回收內存,還容易造成循環引用問題。

runtime.AddCleanup:更好的資源清理方案

Go 團隊也意識到了這些問題。

隨著 Go 語言的不斷演進,推出了更優雅的解決方案:runtime.AddCleanup和weak.Pointer。

核心改進

runtime.AddCleanup的最大改進在于:清理函數不會接收原始對象作為參數。

這個設計直接解決了 finalizer 的兩大痛點:

  1. 避免對象復活問題。
  2. 支持循環引用的對象清理。

看個實際例子,用內存映射文件來演示:

//go:build unix

package main

import (
    "os"
    "runtime"
    "syscall"
)

type MemoryMappedFile struct {
    data []byte
}

func NewMemoryMappedFile(filename string) (*MemoryMappedFile, error) {
    f, err := os.Open(filename)
    if err != nil {
        returnnil, err
    }
    defer f.Close()

    // 獲取文件信息,主要是文件大小
    fi, err := f.Stat()
    if err != nil {
        returnnil, err
    }

    // 提取文件描述符
    conn, err := f.SyscallConn()
    if err != nil {
        returnnil, err
    }

    var data []byte
    connErr := conn.Control(func(fd uintptr) {
        // 創建內存映射
        data, err = syscall.Mmap(int(fd), 0, int(fi.Size()),
            syscall.PROT_READ, syscall.MAP_SHARED)
    })
    if connErr != nil {
        returnnil, connErr
    }
    if err != nil {
        returnnil, err
    }

    mf := &MemoryMappedFile{data: data}

    // 關鍵來了:設置清理函數
    cleanup := func(data []byte) {
        syscall.Munmap(data) // 忽略錯誤
    }
    runtime.AddCleanup(mf, cleanup, data)

    return mf, nil
}

看到區別了嗎?runtime.AddCleanup接受三個參數:

  1. 要監控的對象:mf。
  2. 清理函數:cleanup。
  3. 清理參數:data。

當mf不再可達時,清理函數會被調用,但接收的參數是data,而不是mf本身。

這樣設計的好處是顯而易見的:

  • mf對象可以立即被回收,不需要等待清理函數執行。
  • 即使mf存在循環引用,也不會阻止清理函數的執行。
  • 內存回收效率大大提高。

weak.Pointer:安全的弱引用

弱指針是另一個很重要的特性。

weak.Pointer允許我們引用一個對象,但不會阻止垃圾回收器回收它。

實際應用場景

繼續用內存映射文件的例子,假設我們的程序經常需要映射相同的文件,為了避免重復的系統調用開銷,我們想要建立一個緩存。

但如果用普通的 map 來緩存,就會面臨一個問題:什么時候刪除緩存 k/v?

弱指針完美解決了這個問題:

package main

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

var cache sync.Map // map[string]weak.Pointer[MemoryMappedFile]

func NewCachedMemoryMappedFile(filename string) (*MemoryMappedFile, error) {
    var newFile *MemoryMappedFile

    for {
        // 嘗試從緩存加載現有值
        value, ok := cache.Load(filename)
        if !ok {
            // 沒找到緩存,需要時創建新的映射文件
            if newFile == nil {
                var err error
                newFile, err = NewMemoryMappedFile(filename)
                if err != nil {
                    returnnil, err
                }
            }

            // 嘗試安裝新的映射文件
            wp := weak.Make(newFile)
            var loaded bool
            value, loaded = cache.LoadOrStore(filename, wp)
            if !loaded {
                // 成功安裝,設置清理函數來刪除緩存條目
                runtime.AddCleanup(newFile, func(filename string, wp weak.Pointer[MemoryMappedFile]) {
                    // 只有當弱指針相等時才刪除,防止誤刪
                    cache.CompareAndDelete(filename, wp)
                }, filename, wp)
                return newFile, nil
            }
            // 有人搶先安裝了文件,繼續循環檢查
        }

        // 檢查緩存條目是否有效
        if mf := value.(weak.Pointer[MemoryMappedFile]).Value(); mf != nil {
            return mf, nil
        }

        // 發現了等待清理的空條目,主動刪除
        cache.CompareAndDelete(filename, value)
    }
}

這個實現很巧妙:

  1. 弱指針緩存:緩存中存儲的是弱指針,不會阻止對象被回收
  2. 自動清理:當對象不再可達時,清理函數會自動刪除緩存條目
  3. 并發安全:使用sync.Map和CompareAndDelete確保并發安全

弱指針的關鍵特性

通過這個例子,我們可以看到弱指針的幾個重要特性:

  1. 可比較性:弱指針是可比較的,即使指向的對象已經被回收
  2. 穩定身份:每個弱指針都有獨立的身份標識
  3. 安全訪問:通過Value()方法安全訪問,返回 nil 表示對象已被回收

通用緩存實現

基于這些特性,我們甚至可以實現一個通用的弱引用緩存:

type Cache[K comparable, V any] struct {
    create func(K) (*V, error)
    m      sync.Map
}

func NewCache[K comparable, V any](create func(K) (*V, error)) *Cache[K, V] {
    return &Cache[K, V]{create: create}
}

func (c *Cache[K, V]) Get(key K) (*V, error) {
    var newValue *V

    for {
        value, ok := c.m.Load(key)
        if !ok {
            if newValue == nil {
                var err error
                newValue, err = c.create(key)
                if err != nil {
                    returnnil, err
                }
            }

            wp := weak.Make(newValue)
            var loaded bool
            value, loaded = c.m.LoadOrStore(key, wp)
            if !loaded {
                runtime.AddCleanup(newValue, func(key K, wp weak.Pointer[V]) {
                    c.m.CompareAndDelete(key, wp)
                }, key, wp)
                return newValue, nil
            }
        }

        if v := value.(weak.Pointer[V]).Value(); v != nil {
            return v, nil
        }

        c.m.CompareAndDelete(key, value)
    }
}

簡單來說,這就是一個可以自動清理過期條目的緩存,非常適合那些創建成本較高但生命周期不確定的對象。

小心 “坑”

雖然這兩個新特性很強大,但使用時還是要注意以下講到的幾個坑。

1. 避免循環引用

清理函數不能捕獲要監控的對象,否則清理函數永遠不會執行:

// 錯誤示例:清理函數捕獲了mf
runtime.AddCleanup(mf, func() {
    // 這里引用了mf,會導致清理函數永遠不執行
    fmt.Printf("清理 %p\n", mf)
}, nil)

// 正確示例:通過參數傳遞需要的信息
runtime.AddCleanup(mf, func(addr uintptr) {
    fmt.Printf("清理 %p\n", unsafe.Pointer(addr))
}, uintptr(unsafe.Pointer(mf)))

2. 弱指針作為 map 鍵的陷阱

當弱指針作為 map 鍵時,被引用的對象不能從對應的值可達,否則對象永遠不會被回收:

// 有問題的設計
type Node struct {
    name string
}

var registry = make(map[weak.Pointer[Node]]*Node)

// 這樣會導致Node永遠不被回收
func badRegister(n *Node) {
    wp := weak.Make(n)
    registry[wp] = n  // 值直接引用了對象
}

3. 非確定性行為

清理函數和弱指針的行為是非確定性的,依賴于垃圾回收器的運行時機。

測試這類代碼時需要特別小心,可能需要主動觸發 GC:

func TestCleanup(t *testing.T) {
    // 創建對象并設置清理
    var cleaned bool
    obj := &MyObject{}
    runtime.AddCleanup(obj, func() {
        cleaned = true
    })

    // 移除強引用
    obj = nil

    // 強制觸發GC
    runtime.GC()
    runtime.GC()  // 可能需要多次

    if !cleaned {
        t.Error("清理函數未執行")
    }
}

總結

這兩個新特性真的很實用,核心原因在于:

  1. runtime.AddCleanup:比傳統 finalizer 更高效,避免了對象復活問題
  2. weak.Pointer 提供了安全的弱引用機制,非常適合構建緩存和避免內存泄漏
  3. 組合使用:可以構建出強大的內存管理模式,比如自清理緩存

雖然這些是高級特性,使用時需要格外小心,但對于那些對性能有極致要求的場景,它們提供了前所未有的靈活性。

責任編輯:武曉燕 來源: 腦子進煎魚了
相關推薦

2025-02-07 09:18:05

機制Go函數

2016-05-11 10:29:54

Spark Strea數據清理Spark

2025-05-22 09:32:23

2013-09-16 16:48:50

Android優化軟引用

2024-10-09 08:54:31

2025-07-16 09:16:36

2013-08-19 17:14:04

.Net強引用弱引用

2020-02-09 17:23:17

Python數據字典

2024-05-20 08:58:13

Java引用類型垃圾回收器

2025-10-11 08:09:12

2020-12-02 09:01:40

Java基礎

2015-07-08 16:28:23

weak生命周期

2009-06-19 16:19:23

Java對象引用

2016-03-02 09:34:03

runtime消息ios開發

2012-03-20 14:17:33

活動目錄

2018-11-16 16:10:28

JavaOOM編程語言

2025-05-14 03:00:00

Go語言控制

2025-02-12 11:53:18

2025-04-02 07:29:14

2018-10-14 15:52:46

MySQL數據清理數據庫
點贊
收藏

51CTO技術棧公眾號

一二三四社区欧美黄| 国产一区二区三区免费| 国产一区二区三区网站| 日韩爱爱小视频| 超碰在线最新| caoporn国产精品| 国产成人97精品免费看片| 免费在线观看黄色小视频| theporn国产在线精品| 色久优优欧美色久优优| 日本a级片在线播放| 黄色片在线免费看| 国产成人精品1024| 国产精品劲爆视频| 国产无码精品在线播放| 日韩中文字幕高清在线观看| 亚洲黄一区二区| 久久黄色片网站| 成人勉费视频| 亚洲图片一区二区| 亚洲一二三区在线| 亚洲人妻一区二区三区| 国产乱对白刺激视频不卡| 日韩av电影在线播放| 久久艹精品视频| 日韩系列欧美系列| 精品五月天久久| 激情av中文字幕| 91麻豆精品国产综合久久久 | 国产精品无码免费专区午夜| 国产精品一二三区视频| 91网址在线看| 国产精品一区二区在线观看| av综合在线观看| 久久99精品国产91久久来源| 国产成人av在线| 国产成人精品a视频一区| 一本一道久久综合狠狠老 | 成人午夜在线影视| 国产精品天美传媒| 日韩精品国内| 国产中文在线视频| 99久久综合狠狠综合久久| 国产精品国模大尺度私拍| 国产乱叫456在线| 久久99国产精品免费| 国产成人精品视频| 国产女主播喷水视频在线观看| 亚洲精品九九| 91精品国产高清久久久久久久久| 国产亚洲成人av| 国产精品激情电影| 欧美激情一区二区三区高清视频| 欧美三级小视频| 欧美视频二区| 高清一区二区三区日本久| 久久久久亚洲天堂| 在线国产精品一区| 91高清视频在线免费观看| 国产成人精品一区二三区| 亚洲激情亚洲| 欧美综合在线第二页| 日韩欧美三级在线观看| 国产精品久久久久久模特| 韩国日本不卡在线| 手机看片久久久| 免费在线观看一区二区三区| 国产日韩欧美自拍| 国产强被迫伦姧在线观看无码| 国模无码大尺度一区二区三区| 亚洲综合色激情五月| 蜜臀久久99精品久久久| 91在线观看免费视频| 日本10禁啪啪无遮挡免费一区二区| jizzjizz在线观看| 最好看的中文字幕久久| 少妇一晚三次一区二区三区| 蜜桃视频www网站在线观看| 色婷婷综合久久| 欧美视频第三页| 婷婷久久免费视频| 精品国产免费人成在线观看| 亚洲人成人无码网www国产| 成人vr资源| 欧美日韩国产成人在线| 伊人中文字幕在线观看| 精品一区二区三区日韩| 99九九电视剧免费观看| 日韩午夜影院| 亚洲视频一区二区在线| heyzo亚洲| 日本黄色成人| 亚洲国产精品系列| аⅴ天堂中文在线网| 欧美一区成人| 国产98色在线| 亚洲AV无码成人片在线观看| 久久久久久久久久久黄色| 最近免费观看高清韩国日本大全| 亚洲欧洲高清| 欧美一区二区三区系列电影| 亚洲乱码国产乱码精品精大量| 婷婷综合在线| 国产91色在线| 亚洲精品无amm毛片| 国产午夜精品一区二区三区视频| 男人天堂新网址| 第84页国产精品| 日韩精品一区二区三区中文精品| 伊人网伊人影院| 欧美女激情福利| 国产精品一区二区三区久久久| 天堂av资源在线| 中文字幕视频一区| 欧洲熟妇精品视频| 狠狠久久伊人| 九九九久久久久久| 中文字幕 欧美激情| 91污片在线观看| 日韩小视频网站| 国产精品日本一区二区三区在线 | a级大片在线观看| 精品91在线| 亚洲一区二区中文| avtt在线播放| 欧美又粗又大又爽| 中文字幕在线看高清电影| 亚洲美女黄网| 超碰97国产在线| 菠萝蜜视频国产在线播放| 欧美色中文字幕| 这里只有久久精品| 亚洲欧美清纯在线制服| 国产视频一区二区三区四区| 91精品久久| 欧美一区二区三区在线| 潘金莲一级黄色片| 久久精品国产77777蜜臀| 日本三级中国三级99人妇网站| 日本乱码一区二区三区不卡| 亚洲成年人在线| 久久久久久天堂| 成人在线视频一区| 免费的一级黄色片| 亚洲国产中文在线二区三区免| 麻豆国产va免费精品高清在线| 在线观看免费黄色小视频| 国产视频一区不卡| 日韩欧美在线免费观看视频| 日本不卡高清| 国产九九精品视频| 日本天堂在线观看| 在线播放国产精品二区一二区四区| 国产极品视频在线观看| 免费人成网站在线观看欧美高清| 亚洲成色www久久网站| h1515四虎成人| 日韩一级裸体免费视频| 91theporn国产在线观看| 中文字幕一区日韩精品欧美| 中文字幕一区二区三区四| 欧美日韩一区二区国产| 韩国精品一区二区三区六区色诱| 最近高清中文在线字幕在线观看1| 日韩精品视频在线免费观看 | 日韩不卡手机在线v区| 日韩精品不卡| 国产精品一区二区三区www| 九九热这里只有在线精品视| 蜜臀久久精品久久久久| 欧美性20hd另类| 亚洲女同二女同志奶水| 国产精品资源在线| www.日本少妇| 国产亚洲一区二区三区不卡| 成人亲热视频网站| 女同视频在线观看| 亚洲乱码一区二区| 国产精品一区二区av白丝下载 | 青草全福视在线| 国产伦乱精品| 国产精品a久久久久久| 麻豆传媒视频在线观看| 精品久久久久99| 国产女主播喷水视频在线观看 | 欧美成人免费小视频| 欧美一区二区公司| 在线视频中文字幕一区二区| 国产稀缺精品盗摄盗拍| 99精品桃花视频在线观看| 三级a在线观看| 国产精品分类| 偷拍视频一区二区| gogo久久日韩裸体艺术| 国产91在线播放九色快色| 影院在线观看全集免费观看| 日韩精品亚洲元码| 国产剧情精品在线| 精品久久久久久亚洲国产300| 黄色一级片一级片| av一区二区三区| 一级做a免费视频| 亚洲欧美日韩精品一区二区| 美女在线免费视频| 中文字幕精品影院| 国产精品theporn88| 激情久久一区二区| 欧美一级免费视频| 少女频道在线观看免费播放电视剧| 精品香蕉在线观看视频一| 国产高清视频免费| 欧美色涩在线第一页| 五月天综合激情| 一二三区精品福利视频| 手机免费观看av| 久久午夜羞羞影院免费观看| 久久久久亚洲av无码网站| 免费成人在线观看| 欧美日韩国产精品激情在线播放| 欧美午夜视频| 免费看污污视频| 手机亚洲手机国产手机日韩| 欧美国产一二三区| 老司机精品在线| 高清av免费一区中文字幕| 精品国产黄a∨片高清在线| 人人爽久久涩噜噜噜网站| 高清电影在线免费观看| 欧美精品免费在线| 超碰电影在线播放| 久久精品国产成人| 欧美日韩在线看片| 最近2019中文字幕在线高清| 九色在线视频| 亚洲色无码播放| 日本国产在线| 亚洲精品永久免费精品| 日本护士...精品国| 亚洲精品99久久久久中文字幕| 精品国产av一区二区| 8x8x8国产精品| 国产伦精品一区二区三区四区| 欧美视频一二三区| 国产亚洲久一区二区| 欧美三级在线看| 在线播放精品视频| 欧美午夜不卡视频| 亚洲视频中文字幕在线观看| 欧美日韩一区二区三区四区| 姑娘第5集在线观看免费好剧| 欧洲中文字幕精品| 亚洲无码久久久久| 制服丝袜av成人在线看| 国产白浆在线观看| 精品欧美黑人一区二区三区| 亚洲精品一区二区三区蜜桃| 亚洲第一页在线| 香蕉人妻av久久久久天天| 亚洲精品永久免费| melody高清在线观看| 精品国产一区二区三区久久狼黑人 | 日韩黄色在线视频| 韩曰欧美视频免费观看| 中文字幕手机在线视频| 欧美影院午夜播放| 国产免费av电影| 精品国产欧美一区二区| 日韩a在线观看| 中文字幕精品—区二区| 91精品久久久| 91黑丝在线观看| 中文.日本.精品| 91在线国产电影| 老汉色老汉首页av亚洲| 欧美12av| 7777久久香蕉成人影院| cao在线观看| 日产欧产美韩系列久久99| 亚洲小视频网站| 成人精品gif动图一区| 久久av无码精品人妻系列试探| 国产精品美女久久久久高潮| 九九热视频精品| 色欧美乱欧美15图片| 国产毛片一区二区三区va在线| 亚洲国内精品在线| 第九色区av在线| 欧美夫妻性生活xx| 欧美性理论片在线观看片免费| 91亚洲精品久久久| 欧美激情15p| 在线播放 亚洲| 免费视频一区二区三区在线观看| 久久人人爽av| 97aⅴ精品视频一二三区| 国产真人真事毛片视频| 午夜影院久久久| 97超视频在线观看| 日韩av综合网站| 91最新在线视频| 国产91色在线免费| 成人高潮视频| 亚洲一区二区三区午夜| 91久久黄色| 欧美高清精品一区二区| 欧美韩国日本综合| 国产成人一区二区三区影院在线| 777亚洲妇女| 成人免费在线视频网| 性欧美xxxx交| av在线亚洲一区| 日本在线高清视频一区| 亚洲人成高清| 日本泡妞xxxx免费视频软件| 国产精品电影院| 日韩欧美国产另类| 日韩av在线一区二区| 黄网av在线| 亚洲va国产va天堂va久久| 日韩成人精品一区| 日韩免费高清在线| 99国产精品久久久久久久久久久 | 秋霞影院午夜丰满少妇在线视频| 欧美亚洲一级片| 国产精品网址| 免费视频爱爱太爽了| 国产一区二区不卡在线| 网爆门在线观看| 欧美日韩一区小说| 电影av一区| 国产精品免费一区二区三区都可以| 九九综合久久| 亚洲中文字幕无码不卡电影| 99久久综合精品| 精品美女久久久久| 日韩激情第一页| 在线观看网站免费入口在线观看国内| 国产日韩三区| 国产日韩亚洲| 中文字幕av网址| 日本高清不卡在线观看| 欧美日韩国产亚洲沙发| 欧美最猛性xxxxx(亚洲精品)| 开心激情综合| 日韩有码免费视频| 久久免费电影网| 无码日韩精品一区二区| 亚洲欧美一区二区三区四区| 欧美成人黑人| 神马影院我不卡| 久久99国产精品麻豆| 激情无码人妻又粗又大| 3d动漫精品啪啪| 少妇视频在线| 国产亚洲自拍偷拍| 国产日韩一区| 成人激情五月天| 9191成人精品久久| 天天干在线视频论坛| 国产精品一区二区欧美| 99精品久久| 无码少妇一区二区| 欧美人狂配大交3d怪物一区| 99福利在线| 国产综合精品一区二区三区| 性欧美xxxx大乳国产app| 久久久久久国产免费a片| 欧美猛男gaygay网站| av在线看片| 好吊色欧美一区二区三区视频| 久久久久国产精品午夜一区| 久久久久亚洲AV成人无在| 欧美一区二区久久久| 1024在线看片你懂得| 日韩精品一区二区三区四区五区| 久久精品国产网站| 久久久国产精华液| 日韩精品在线影院| 日本免费成人| 男人日女人视频网站| 国产校园另类小说区| 99久久精品国产色欲| 午夜免费日韩视频| 日韩理论电影| 国产伦精品一区三区精东| 欧美色窝79yyyycom| 阿v视频在线| 亚洲最新在线| 91在线精品一区二区| 一级aaaa毛片| 91精品国产99| 亚洲视频在线免费| 亚洲第一香蕉网| 日韩欧美国产小视频| 中文字幕在线中文字幕在线中三区| 国产又爽又黄ai换脸| 91欧美一区二区| 99国产精品一区二区三区| 日本人成精品视频在线| 欧美阿v一级看视频|