-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.
Milestone
Description
Because of the internal representation of unique values, making chains of N unique.Handles requires at minimum N GC cycles to reclaim. The root of the issue is the fact that we store canonical values in something like a map[T]weak.Pointer[T]. They key in the map keeps handles further down the chain alive until they're removed from the map.
We can fix this by using a more bespoke data structure that only stores canonical values as weak.Pointer[T] and nothing else, as in https://go.dev/cl/650256.
Below is a demonstration of the issue.
type nestedHandle struct {
next Handle[testNestedHandle]
arr [6]int
}
var n0, n1, n2, n3 nestedHandle
func TestNestedHandle(t *testing.T) {
n0 = nestedHandle{arr: [6]int{1, 2, 3, 4, 5, 6}}
n1 = nestHandle(n0)
n2 = nestHandle(n1)
n3 = nestHandle(n2)
n0 = nestedHandle{}
n1 = nestedHandle{}
n2 = nestedHandle{}
n3 = nestedHandle{}
runtime.GC() // Today, this will only enable n3 to be reclaimed.
}
func nestHandle(n nestedHandle) nestedHandle {
return nestedHandle{
next: unique.Make(n),
arr: n.arr,
}
}
https://go.dev/cl/650256 resolves this issue.
Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.