-
Notifications
You must be signed in to change notification settings - Fork 18k
x/net/http2: Requesting data via http2 and closing the response body early uses 3-5x more memory than via http1 #16656
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
FWIW I'm seeing something similar while reading files from Google Cloud Storage using that API. Again, setting |
This sounds very similar to #15930 which was marked fixed. |
GC trace is also very different:
Versus:
|
/cc @bradfitz |
ping @bradfitz |
I'll take ownership of this, but it's pretty low priority for now. If others could investigate, I'd appreciate it. /cc @bmizerany too |
This is actually expected. http2's Transport is always reading from the peer and has a initial window size of bytes it'll read, compared to http1. So I would expect more allocations. Is this actually a problem? I don't imagine reading part of the response happens often. Closing until there's reason to believe we need to change anything. |
Thanks for looking into this issue! |
go version
)?(It was reported to also occur on Go 1.7rc6)
go env
)?Writing a program that requests a larger file via HTTP GET, but only reads the first few bytes of the response body, then calls
Close()
on it.I expect that the HTTP download is aborted soon after the body is closed. Especially, I expect that only very little data is read from the server and stored in a buffer, regardless of the underlying transmission protocol.
Requesting and then closing the body takes a lot of memory. Disabling http2 reduces this a lot.
At https://fd0.me/tmp/random100MB I've created a file with 100MB of random data. The following Go program was used to request the file, read the first 100 bytes, and then close the response body several times in a loop:
With Go 1.6.3 standard http client (uses http2), this takes about 500MB of memory:
Disabling http2 reduces this a lot:
Server logs (Caddy in this case) show that much more data is actually read per request, ~2.5MiB via HTTP2 vs. ~200KiB via HTTP1:
In the real world, this came up as restic/restic#565 where a user described that accessing backup data (restic is a backup program) on s3 over http2 is impossible because the OOM killer terminates the process.
I'm not really sure what's going on here, or even if this is a bug at all.
I have a hunch that, in addition to loading more data, the http2 client code in this case forgets to free some buffers.
What do you think? Please feel free to use the URL above to test this.
The text was updated successfully, but these errors were encountered: