Golang 1.24: New Std-Lib weak
Use weak.Pointer to flexibly manage objects
Go 1.24 introduces a new std-lib package called weak, which allows you to create safe references to *T without preventing the garbage collector (GC) from reclaiming the memory associated with *T.
The weak package provides ways to safely reference memory weakly, meaning without preventing its reclamation by the garbage collector.
Much like OS.ROOT, weak is a feature that has existed in other programming languages for some time, including:
- In
Java,WeakReferenceandSoftReferenceare classic implementations primarily used for caching and object pools. These references allow automatic garbage collection when the JVM detects a memory shortage. - In
Python, theweakrefmodule allows the creation of weak references, commonly used to prevent circular reference issues or for caching. - In
C++,std::weak_ptrwas introduced alongsidestd::shared_ptrto solve circular dependency problems with shared pointers. - In
Rust,Weakis the weak reference version ofRcandArc, which helps prevent circular references and provides more flexible memory management.
Simple Definition of weak
The weak package is defined with just a Make method and a Value method.

By using weak.Make, a weak.Pointer is created, and if the original *T has not been GC, we can access its address through weak.Pointer.Value. If the object has been collected, the Value will return nil.
You can see an example implementation of weak here:
Example Output:
➜ weak git:(main) ✗ gotip version
go version devel go1.24-18b5435 Sun Dec 15 21:41:28 2024 -0800 darwin/arm64
➜ weak git:(main) ✗ gotip run main.go
originalObject:addr 14000010050
weakPtr addr:{1400000e0d0},size:8
First GC :value: Hello, World!
originalObject clean at: 1734340907
Second GC: Weak reference value is nilIn this example:
- We create a
stringvariableoriginalObjectand useweak.Maketo create aweak.PointercalledweakPtr. - During the first garbage collection (GC), since
originalObjectis still in use,weakPtr.Valuereturns the address oforiginalObject. - In the second GC, since
originalObjectis no longer used, it is collected by the GC, andweakPtr.Valuereturnsnil.
Also, runtime.AddCleanup, a new feature in Go 1.24, works similarly runtime.SetFinalizer by allowing you to execute code when an object is GC. This feature will be covered in more detail later.
Key Takeaways:
weak.Makecreates aweak.Pointer, which hides the actual memory address but does not affect the GC.- If the real object is garbage collected,
weak.Pointer.Valueit will returnnil. Since we don't know when the actual object will be reclaimed, always check the return value ofweak.Pointer.Value.
The Practical Use of weak
Canonicalization Maps
You might remember the unique feature introduced in Go 1.23, which uses a single pointer (8 bytes) to represent multiple identical strings, saving memory. The weak package can achieve similar functionality (In fact, in Go 1.24, unique has been refactored using weak).
Implementing a Fixed-Size Cache
Here’s an example of a fixed-size cache using weak+ list.
In this example:
- We use a fixed-size list and a
Mapto store the position of each key in the list where the value is aweak.Pointerto alist.Element. - When we add a new cache item, we first check if the list is complete. If so, the oldest item is evicted.
- When a key exists in the cache,
Map[key].Valuewill return the address of the list element. If the item is evicted,Map[key].Valuereturnsnil.
This design helps to create an efficient, fixed-size cache system. Using weak a lock-free queue structure allows for even more efficient data handling.
I find weak to be quite helpful in specific scenarios. It's easy to use, and I plan to incorporate it into my projects.
Further Reading on weak:
