Petunjuk yang lemah ialah tambahan baharu kepada Go (tersedia dalam versi 1.24 ) yang membolehkan anda merujuk objek dalam ingatan tanpa menghalangnya daripada menjadi sampah. Catatan blog ini akan memperkenalkan petunjuk yang lemah, menerangkan kegunaannya dan memberikan contoh konkrit untuk menggunakannya untuk membina cache yang cekap memori.
Penunjuk lemah ialah sejenis rujukan khas kepada objek dalam ingatan. Tidak seperti rujukan yang kuat, penunjuk yang lemah tidak menghalang pemungut sampah daripada menuntut semula objek yang dirujuk jika tiada rujukan yang kuat wujud. Ini menjadikan penunjuk lemah sebagai alat yang sangat baik untuk senario di mana anda ingin merujuk objek tetapi tidak mahu mengganggu pengurusan memori automatik Go.
Dalam Go 1.24, petunjuk lemah akan menjadi sebahagian daripada pakej lemah baharu. Mereka berfungsi seperti ini:
Petunjuk lemah bersinar dalam kes di mana kecekapan ingatan adalah penting. Contohnya:
Katakan anda sedang membina cache untuk pelayan web yang menyimpan data yang kerap diakses. Anda mahu cache menyimpan data buat sementara waktu tetapi biarkan pengumpul sampah membersihkan objek yang tidak lagi digunakan di tempat lain.
Begini cara anda boleh melakukannya menggunakan penunjuk lemah:
package main import ( "fmt" "runtime" "sync" "time" "weak" ) // Cache represents a thread-safe cache with weak pointers. type Cache[K comparable, V any] struct { mu sync.Mutex items map[K]weak.Pointer[V] // Weak pointers to cached objects } // NewCache creates a new generic Cache instance. func NewCache[K comparable, V any]() *Cache[K, V] { return &Cache[K, V]{ items: make(map[K]weak.Pointer[V]), } } // Get retrieves an item from the cache, if it's still alive. func (c *Cache[K, V]) Get(key K) (*V, bool) { c.mu.Lock() defer c.mu.Unlock() // Retrieve the weak pointer for the given key ptr, exists := c.items[key] if !exists { return nil, false } // Attempt to dereference the weak pointer val := ptr.Value() if val == nil { // Object has been reclaimed by the garbage collector delete(c.items, key) return nil, false } return val, true } // Set adds an item to the cache. func (c *Cache[K, V]) Set(key K, value V) { c.mu.Lock() defer c.mu.Unlock() // Create a weak pointer to the value c.items[key] = weak.Make(&value) } func main() { // Create a cache with string keys and string values cache := NewCache[string, string]() // Add an object to the cache data := "cached data" cache.Set("key1", data) // Retrieve it if val, ok := cache.Get("key1"); ok { fmt.Println("Cache hit:", *val) } else { fmt.Println("Cache miss") } // Simulate losing the strong reference data = "" runtime.GC() // Force garbage collection // Try to retrieve it again time.Sleep(1 * time.Second) if val, ok := cache.Get("key1"); ok { fmt.Println("Cache hit:", *val) } else { fmt.Println("Cache miss") } }
Tanpa penunjuk yang lemah, cache akan memegang rujukan yang kuat kepada semua objeknya, menghalangnya daripada menjadi sampah yang dikumpul. Ini boleh menyebabkan kebocoran memori, terutamanya dalam pelayan yang berjalan lama di mana objek cache terkumpul dari semasa ke semasa.
Dengan menggunakan penunjuk lemah:
Tanpa petunjuk yang lemah, anda memerlukan pendekatan yang lebih manual, seperti menyemak dan mengalih keluar objek yang tidak digunakan secara berkala, yang menambah kerumitan dan ruang untuk pepijat.
Petunjuk yang lemah sangat sesuai untuk senario seperti:
Walau bagaimanapun, elakkan menggunakan penunjuk lemah sebagai ganti rujukan kukuh apabila anda memerlukan akses terjamin kepada objek. Sentiasa pertimbangkan keperluan memori dan prestasi aplikasi anda.
Penunjuk lemah ialah alat yang berkuasa untuk membina aplikasi cekap memori dalam Go. Ciri kecil ini boleh memberi impak besar dalam senario di mana pengurusan memori dengan cekap adalah kritikal.
Atas ialah kandungan terperinci Menggunakan Penunjuk Lemah dalam Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!