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
x/net/http2/hpack: lookup maps for the dynamic table leak despite evictions #19756
Comments
@rodaine, thanks for the debugging! If you want to send a fix, please do. Otherwise @tombergan or I can handle it too. Let us know. |
No sweat! Pushing the patch momentarily :) |
I trust you've discovered https://golang.org/doc/contribute.html ? (Sorry in advance for the wall of words. It tries to be comprehensive but it might be intimidating. There aren't many steps in the end.) |
Yessir! |
CL https://golang.org/cl/38781 mentions this issue. |
An earlier performance change, https://golang.org/cl/37406, made headerFieldTable lookups O(1). The entries in the maps used to perform these lookups were not evicted along with the original field elements, however causing a gradual memory leak. This is most apparent when the headers have highly variable content such as request IDs or timings. Fixes golang/go#19756 Change-Id: Icdb51527eb671925216350ada15f2a1336ea3158 Reviewed-on: https://go-review.googlesource.com/38781 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Tom Bergan <tombergan@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?What did you do?
Adding the following test to the current master of x/net/http2/hpack/tables_test.go:
And running
go test -v -run TestHeaderFieldTable_LookupMapEviction
from that directoryWhat did you expect to see?
What did you see instead?
More context
When the load to a gRPC service was recently ramped up, we were alerted to a memory leak which took approximately 24hrs to consume all the RAM and die. Getting the heap profile off the running service, the vast majority of the objects were originating from
hpack.(*dynamicTable).add
andhpack.(*Decoder).readString
:Digging into that code, there was a performance change made last month that improved lookup times considerably by caching the header IDs in
byName
andbyNameValue
maps. Unfortunately, it doesn't appear that the map entries are evicted, but instead set to zero:This eventually (but somewhat slowly) grows huge for variable headers like request IDs, timings, etc. Rolling back the package to the prior SHA immediately rectified the problem. I'm working on a patch to replace the above to use
delete()
instead. Curious if there is a reason to not?The text was updated successfully, but these errors were encountered: