惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Engineering at Meta
Engineering at Meta
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
M
MIT News - Artificial intelligence
IT之家
IT之家
博客园 - 【当耐特】
U
Unit 42
云风的 BLOG
云风的 BLOG
L
LangChain Blog
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
宝玉的分享
宝玉的分享
N
Netflix TechBlog - Medium

VictoriaMetrics: Simple & Reliable Monitoring for Everyone on VictoriaMetrics

Operator now has Long-Term Support (LTS) version Multi-tiered Observability: A Practical Way to Handle Diverse Workloads VictoriaMetrics April 2026 Ecosystem Updates Not All Telemetry Requires Premium Pricing VictoriaMetrics at KubeCon Amsterdam: Community Highlights What's new in VictoriaMetrics Anomaly Detection (Q1 2026) What's New in VictoriaMetrics Cloud Q1 2026? Logs, MCP Server, Better Alerting, and... a Secret Project VictoriaMetrics at KubeCon: Optimizing Tail Sampling in OpenTelemetry with Retroactive Sampling VictoriaMetrics March 2026 Ecosystem Updates Observability Lessons From OpenAI Benchmarking Kubernetes Log Collectors: vlagent, Vector, Fluent Bit, OpenTelemetry Collector, and more VictoriaMetrics February 2026 Ecosystem Updates VictoriaMetrics at FOSDEM, Cloud Native Days France, and CfgMgmtCamp Ghent VictoriaLogs in VictoriaMetrics Cloud: Fast, Cost-Effective Log Management is Here What’s new in VictoriaMetrics Anomaly Detection (2025) VictoriaMetrics January 2026 Ecosystem Updates VictoriaLogs Basics: What You Need to Know, with Examples & Visuals What's New in VictoriaMetrics Cloud Q4 2025? New tiers, more deployment options, IaC and alerting rules. Vibe coding tools observability with VictoriaMetrics Stack and OpenTelemetry How a US Software Provider Improved Traffic Alerting with VictoriaMetrics Anomaly Detection VictoriaMetrics 2025 Developer Experience: A Year in Review Spotify’s performance & control across large monitoring environments with VictoriaMetrics VictoriaMetrics Achieves Red Hat OpenShift Operator Certification Our latest updates across the VictoriaMetrics Observability ecosystem New Capacity Tiers in VictoriaMetrics Cloud Announcing 1B+ Downloads & Product Development With Logs, Traces, Metrics AI Agents Observability with OpenTelemetry and the VictoriaMetrics Stack Discarding gRPC-Go: The Story Behind OTLP/gRPC Support in VictoriaTraces What's New in VictoriaMetrics Cloud Q3 2025? From new region in Asia to proactive alerts How DreamHost Slashed Memory Usage by 80% and Scaled to 76 Million Time Series
Weak Pointers in Go: Why They Matter Now
Phuong Le · 2024-11-29 · via VictoriaMetrics: Simple & Reliable Monitoring for Everyone on VictoriaMetrics

When we talked about string interning earlier, we mentioned a concept that Go uses to implement its unique map feature: the “weak pointer.” We kind of breezed through it back then to stay on track with the main flow of that article.

If you haven’t checked that piece out yet, I’d highly recommend giving it a read: Inside Go’s Unique Package: String Interning Simplified. It’s one of those optimization tricks that makes VictoriaMetrics’ products faster. You can read it before or after this one—totally up to you.

So, what’s a weak pointer?

#

A weak pointer is basically a way to reference a chunk of memory without locking it down, so the garbage collector can clean it up if no one else is actively holding onto it.

“Why even bother with weak pointers? Does Go even have them?”

Well, yes, Go does have the weak pointer concept. It’s part of the weak package, which is tied pretty closely to the Go runtime. Interestingly, it used to be more of an internal tool, but recently there’s been a push to make it public through this proposal.

Pretty cool, right?

The key thing about weak pointers is that they’re safe. If the memory they’re pointing to gets cleaned up, the weak pointer automatically becomes nil — so there’s no risk of accidentally pointing to freed memory. And when you do need to hold onto that memory, you can convert a weak pointer into a strong one. That strong pointer tells the garbage collector, “Hey, hands off this memory while I’m using it.”

“Wait, it just turns into nil automatically? That sounds… risky.”

Yep, weak pointers can definitely become nil — sometimes at moments you’re not expecting.

They’re trickier to use than regular pointers. At any point, a weak pointer can turn nil if the memory it points to gets cleaned up. This happens when no strong pointers are holding onto that memory. So, it’s really important to always check if the strong pointer that you just converted from a weak pointer is nil.

Now, about when this cleanup happens — it’s not immediate. Even when no one’s referencing the memory, the cleanup moment is totally up to the garbage collector.

“Alright, show me some code!”

At the time of writing, the weak package isn’t officially released yet. It’s expected to land in Go 1.24. But we can sneak a peek at the source code and play around with it. The package gives you two main APIs:

  • weak.Make: creates a weak pointer from a strong pointer.
  • weak.Pointer[T].Strong: converts a weak pointer back into a strong pointer.

Here’s an example:

type T struct {
  a int
  b int
}

func main() {
  a := new(string)
  println("original:", a)

  // make a weak pointer
  weakA := weak.Make(a)

  runtime.GC()

  // use weakA
  strongA := weakA.Strong()
  println("strong:", strongA, a)

  runtime.GC()

  // use weakA again
  strongA = weakA.Strong()
  println("strong:", strongA)
}

// Output:
// original: 0x1400010c670
// strong: 0x1400010c670 0x1400010c670
// strong: 0x0

And here’s what’s happening in the code:

  1. After the first garbage collection (runtime.GC()), the weak pointer weakA still points to the memory because we’re still using the variable a in the println("strong:", strongA, a) line. The memory can’t be cleaned up yet since it’s in use.
  2. But when the second garbage collection runs, the strong reference (a) isn’t used anymore. That means the garbage collector can safely clean up the memory, leaving weakA.Strong() to return nil.

Now, if you try this code with something other than a string pointer—like a *int, *bool, or some other type, you might notice different behavior, the last strong output may not be nil.

This has to do with how Go handles “tiny objects” like int, bool, float32, float64, etc. These types are allocated as tiny objects, and even if they’re technically unused, the garbage collector might not clean them up right away during garbage collection. To understand more about this, you can dive deeper into tiny object allocation in Go Runtime Finalizer and Keep Alive.

Weak pointers can be really practical for managing memory in specific scenarios.

  • For example, they’re great for canonicalization maps — situations where you only want to keep one copy of a piece of data around. This ties back to our earlier discussion on string interning.
  • Another case is when you want the lifespan of some memory to match the lifespan of another object, similar to how JavaScript’s WeakMap works. WeakMaps allow objects to be cleaned up automatically when they’re no longer in use.

So, the main benefit of weak pointers is they let you tell the garbage collector, “Hey, it’s okay to get rid of this resource if no one’s using it — I can always recreate it later.” This works well for objects that take up significant memory but don’t need to stick around unless they’re actively being used.

How do weak pointers work?

#

Interestingly, weak pointers don’t actually point directly to the memory they reference. Instead, they’re simple structs (using generics) that hold an “indirection object.” This object is tiny, just 8 bytes, and it points to the actual memory target.

type Pointer[T any] struct {
	u unsafe.Pointer
}

Weak pointers referencing memory via indirection

Weak pointers referencing memory via indirection

Why design it this way?

This setup lets the garbage collector clean up weak pointers to a specific object all at once, efficiently. When it decides the memory should be freed, the collector only needs to set the pointer in the indirection object to nil (or 0x0). It doesn’t have to go around updating each weak pointer individually.

GC reclaims memory, updates weak pointer link

GC reclaims memory, updates weak pointer link

On top of that, this design supports equality checks (==). Weak pointers created from the same original pointer will be treated as “equal,” even after the object they point to has been garbage collected.

func main() {
	a := new(string)

	// make a weak pointers
	weakA := weak.Make(a)
	weakA2 := weak.Make(a)

	println("Before GC: Equality check:", weakA == weakA2)

	runtime.GC()

	// Test their equality
	println("After GC: Strong:", weakA.Strong(), weakA2.Strong())
	println("After GC: Equality check:", weakA == weakA2)
}

// Before GC: Equality check: true
// After GC: Strong: 0x0 0x0
// After GC: Equality check: true

This works because weak pointers from the same original object share the same indirection object. When you call weak.Make, if an object already has a weak pointer associated with it, the existing indirection object gets reused instead of creating a new one.

“Wait, isn’t using 8 bytes for an indirection object a bit wasteful?”

It might seem like it, but the author would say, this isn’t a big issue. Weak pointers are typically used in cases where the overall goal is to save memory. For example, in canonicalization maps — where you eliminate duplicates by keeping only one copy of each unique piece of data — you’re already saving a lot of memory by avoiding redundancy.

That said, if you’re using weak pointers in a scenario where there are tons of unique items and few duplicates, you could end up using more memory than expected. So, it’s important to consider the specific use case when deciding if weak pointers are the right tool for the job.

Stay Connected

#

Hi, I’m Phuong Le, a software engineer at VictoriaMetrics. The writing style above focuses on clarity and simplicity, explaining concepts in a way that’s easy to understand, even if it’s not always perfectly aligned with academic precision.

If you spot anything that’s outdated or if you have questions, don’t hesitate to reach out. You can drop me a DM on X(@func25).

Related articles:

Who We Are

#

If you want to monitor your services, track metrics, and see how everything performs, you might want to check out VictoriaMetrics. It’s a fast, open-source, and cost-saving way to keep an eye on your infrastructure.

And we’re Gophers, enthusiasts who love researching, experimenting, and sharing knowledge about Go and its ecosystem.