-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsFixThe 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.Performance
Milestone
Description
type CustomStringer int
func (c CustomStringer) String() string {
time.Sleep(500 * time.Millisecond) // simulate processing time
return string(make([]byte, int(c)))
}
func main() {
processRequest := func(size int) {
fmt.Sprintf("<%v>", CustomStringer(size))
time.Sleep(1 * time.Millisecond) // simulate idle time
}
// Simulate a steady stream of infrequent large requests.
go func() {
for {
processRequest(1 << 28) // 256MiB
}
}()
// Simulate a storm of small requests.
for i := 0; i < 1000; i++ {
go func() {
for {
processRequest(1 << 10) // 1KiB
}
}()
}
// Continually run a GC and track the allocated bytes.
var stats runtime.MemStats
for i := 0; ; i++ {
runtime.ReadMemStats(&stats)
fmt.Printf("Cycle %d: %dB\n", i, stats.Alloc)
time.Sleep(time.Second)
runtime.GC()
}
}
This is a variation of #23199 (comment). See that comment for why this memory leak occurs.
After the 50th GC cycle, this pins 7GiB of heap, when I expect it to use no more than 256MiB.
smasher164
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsFixThe 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.Performance