-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Hi,
I would like to propose an idea (with few questions). I am still learning internals of Go (especially GC subsystem) so I hope my mental model is correct and clear.
Think about following code:
type ss struct {
x int
}
a = make([]ss, ntimes)
for i := 0; i < ntimes; i++ {
a[i] = ss{x: s{}}
}Now, if I change the x int to x *int in the above code, the GC total latency jumps from ~106usec to ~1.6ms, roughly ~10x more overhead. Now, it is due to the fact that now GC needs to mark the pointer field in the structure, IIUC.
I think I am not the only one faced this: https://blog.gopheracademy.com/advent-2018/avoid-gc-overhead-large-heaps/. When there are lots of pointers held in memory, the GC latency increases.
Now I understand that this kind behavior is completely natural. I am more looking for ways to anticipate this kind of behavior during implementation via some kind of counter for observability reasons. This behavior becomes somewhat more subtle(?) if for example x is a string (string itself holds an implicit pointer) or x ia struct that contains a pointer somewhere deep in its definition.
Let me propose an idea:
// run same code as above
runtime.GC()
gcs := new(debug.GCStats)
debug.ReadGCStats(gcs)
fmt.Printf("Last GC total marked pointers:%d\n", gcs.NumPointers)This would give the programmer a deterministic way to benchmark and optimize for allocations if possible. The current approach I am using to debug this is: to manually invoke GC and calculate elapsed time. This is somewhat ok, but IMHO it would be better and more deterministic to have a simple counter. WDYT?
And one more unrelated question just for learning: why we don't have a field for total GC latency (like a wall time), IIUC we currently have PauseTotalwhich shows the duration for STW, but would not it be nice to see whole running
time(total latency)? Probably this is not possible given that it runs concurrently in different goroutines or maybe is not just necessary?
Thanks,