http2: shrink memory to match read data
Perform a shrinking `Realloc()` so that less data is used for HTTP2 reads. PR-URL: https://github.com/nodejs/node/pull/26201 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
e51da1fcad
commit
83e1b97443
@ -1774,17 +1774,8 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
|
|||||||
Http2Scope h2scope(this);
|
Http2Scope h2scope(this);
|
||||||
CHECK_NOT_NULL(stream_);
|
CHECK_NOT_NULL(stream_);
|
||||||
Debug(this, "receiving %d bytes", nread);
|
Debug(this, "receiving %d bytes", nread);
|
||||||
IncrementCurrentSessionMemory(buf.len);
|
|
||||||
CHECK(stream_buf_ab_.IsEmpty());
|
CHECK(stream_buf_ab_.IsEmpty());
|
||||||
|
|
||||||
OnScopeLeave on_scope_leave([&]() {
|
|
||||||
// Once finished handling this write, reset the stream buffer.
|
|
||||||
// The memory has either been free()d or was handed over to V8.
|
|
||||||
DecrementCurrentSessionMemory(buf.len);
|
|
||||||
stream_buf_ab_ = Local<ArrayBuffer>();
|
|
||||||
stream_buf_ = uv_buf_init(nullptr, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Only pass data on if nread > 0
|
// Only pass data on if nread > 0
|
||||||
if (nread <= 0) {
|
if (nread <= 0) {
|
||||||
free(buf.base);
|
free(buf.base);
|
||||||
@ -1794,19 +1785,25 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shrink to the actual amount of used data.
|
||||||
|
char* base = Realloc(buf.base, nread);
|
||||||
|
|
||||||
|
IncrementCurrentSessionMemory(nread);
|
||||||
|
OnScopeLeave on_scope_leave([&]() {
|
||||||
|
// Once finished handling this write, reset the stream buffer.
|
||||||
|
// The memory has either been free()d or was handed over to V8.
|
||||||
|
DecrementCurrentSessionMemory(nread);
|
||||||
|
stream_buf_ab_ = Local<ArrayBuffer>();
|
||||||
|
stream_buf_ = uv_buf_init(nullptr, 0);
|
||||||
|
});
|
||||||
|
|
||||||
// Make sure that there was no read previously active.
|
// Make sure that there was no read previously active.
|
||||||
CHECK_NULL(stream_buf_.base);
|
CHECK_NULL(stream_buf_.base);
|
||||||
CHECK_EQ(stream_buf_.len, 0);
|
CHECK_EQ(stream_buf_.len, 0);
|
||||||
|
|
||||||
// Remember the current buffer, so that OnDataChunkReceived knows the
|
// Remember the current buffer, so that OnDataChunkReceived knows the
|
||||||
// offset of a DATA frame's data into the socket read buffer.
|
// offset of a DATA frame's data into the socket read buffer.
|
||||||
stream_buf_ = uv_buf_init(buf.base, nread);
|
stream_buf_ = uv_buf_init(base, nread);
|
||||||
|
|
||||||
// Verify that currently: There is memory allocated into which
|
|
||||||
// the data has been read, and that memory buffer is at least as large
|
|
||||||
// as the amount of data we have read, but we have not yet made an
|
|
||||||
// ArrayBuffer out of it.
|
|
||||||
CHECK_LE(static_cast<size_t>(nread), stream_buf_.len);
|
|
||||||
|
|
||||||
Isolate* isolate = env()->isolate();
|
Isolate* isolate = env()->isolate();
|
||||||
|
|
||||||
@ -1814,9 +1811,9 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
|
|||||||
// as slices of this array buffer to avoid having to copy memory.
|
// as slices of this array buffer to avoid having to copy memory.
|
||||||
stream_buf_ab_ =
|
stream_buf_ab_ =
|
||||||
ArrayBuffer::New(isolate,
|
ArrayBuffer::New(isolate,
|
||||||
buf.base,
|
base,
|
||||||
nread,
|
nread,
|
||||||
ArrayBufferCreationMode::kInternalized);
|
ArrayBufferCreationMode::kInternalized);
|
||||||
|
|
||||||
statistics_.data_received += nread;
|
statistics_.data_received += nread;
|
||||||
ssize_t ret = Write(&stream_buf_, 1);
|
ssize_t ret = Write(&stream_buf_, 1);
|
||||||
|
@ -8,7 +8,7 @@ const http2 = require('http2');
|
|||||||
|
|
||||||
// Test that maxSessionMemory Caps work
|
// Test that maxSessionMemory Caps work
|
||||||
|
|
||||||
const largeBuffer = Buffer.alloc(1e6);
|
const largeBuffer = Buffer.alloc(2e6);
|
||||||
|
|
||||||
const server = http2.createServer({ maxSessionMemory: 1 });
|
const server = http2.createServer({ maxSessionMemory: 1 });
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user