-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: unexpected heap allocation for large structs in Go 1.24 compared to Go 1.23 #73536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is due to 5a0f2a7
|
The maximum size of a stack-allocated object was lowered to 128KB (from 10MB). We do not make any particular promises about the size at which stack or heap allocations happen. The size threshold (or perhaps other deciding factors other than size) may change from release to release. There is no flag to alter this behavior. |
Environment:
Problem Description:
When compiling the same code containing large struct variables within a function, Go 1.23 allocates these structs on the stack, while Go 1.24 allocates them on the heap (they escape).
Code Example:
Steps to Reproduce:
Save the code above as
main.go
.Compile with Go 1.23 using escape analysis enabled:
go build -gcflags="-m" main.go
Output
Compile with Go 1.24 using escape analysis enabled:
go build -gcflags="-m" main.go
Output
Observed Behavior:
-gcflags="-m"
does not indicate that variablesa
andb
escape to the heap. They appear to be stack-allocated as expected for local variables whose addresses don't escape.-gcflags="-m"
does indicate that variablesa
andb
escape or are moved to the heap (e.g., showing lines like./main.go:17:2: moved to heap: a
and./main.go:18:2: moved to heap: b
).go build -gcflags="-S"
) for both versions confirms the difference in allocation strategy.Expected Behavior:
It was expected that the allocation behavior for these local structs would remain consistent between Go versions, primarily remaining on the stack, unless there's a documented change in escape analysis or stack size limits causing this. If this is an intentional change in Go 1.24 (perhaps related to stack size management or PGO), it would be helpful to have it documented.
Additional Context:
ethtoolGStrings
andethtoolStats
are relatively large (approx 1MB and 256KB, respectively). Is there a new size threshold or heuristic in Go 1.24 causing large local variables to be heap-allocated by default?Thank you for looking into this.
The text was updated successfully, but these errors were encountered: