Skip to content

Commit 8a551b9

Browse files
addaleaxrvagg
authored andcommitted
http2: shrink memory to match read data
Perform a shrinking `Realloc()` so that less data is used for HTTP2 reads. PR-URL: #26201 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 619b5e7 commit 8a551b9

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

src/node_http2.cc

+16-19
Original file line numberDiff line numberDiff line change
@@ -1774,17 +1774,8 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
17741774
Http2Scope h2scope(this);
17751775
CHECK_NOT_NULL(stream_);
17761776
Debug(this, "receiving %d bytes", nread);
1777-
IncrementCurrentSessionMemory(buf.len);
17781777
CHECK(stream_buf_ab_.IsEmpty());
17791778

1780-
OnScopeLeave on_scope_leave([&]() {
1781-
// Once finished handling this write, reset the stream buffer.
1782-
// The memory has either been free()d or was handed over to V8.
1783-
DecrementCurrentSessionMemory(buf.len);
1784-
stream_buf_ab_ = Local<ArrayBuffer>();
1785-
stream_buf_ = uv_buf_init(nullptr, 0);
1786-
});
1787-
17881779
// Only pass data on if nread > 0
17891780
if (nread <= 0) {
17901781
free(buf.base);
@@ -1794,29 +1785,35 @@ void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
17941785
return;
17951786
}
17961787

1788+
// Shrink to the actual amount of used data.
1789+
char* base = Realloc(buf.base, nread);
1790+
1791+
IncrementCurrentSessionMemory(nread);
1792+
OnScopeLeave on_scope_leave([&]() {
1793+
// Once finished handling this write, reset the stream buffer.
1794+
// The memory has either been free()d or was handed over to V8.
1795+
DecrementCurrentSessionMemory(nread);
1796+
stream_buf_ab_ = Local<ArrayBuffer>();
1797+
stream_buf_ = uv_buf_init(nullptr, 0);
1798+
});
1799+
17971800
// Make sure that there was no read previously active.
17981801
CHECK_NULL(stream_buf_.base);
17991802
CHECK_EQ(stream_buf_.len, 0);
18001803

18011804
// Remember the current buffer, so that OnDataChunkReceived knows the
18021805
// offset of a DATA frame's data into the socket read buffer.
1803-
stream_buf_ = uv_buf_init(buf.base, nread);
1804-
1805-
// Verify that currently: There is memory allocated into which
1806-
// the data has been read, and that memory buffer is at least as large
1807-
// as the amount of data we have read, but we have not yet made an
1808-
// ArrayBuffer out of it.
1809-
CHECK_LE(static_cast<size_t>(nread), stream_buf_.len);
1806+
stream_buf_ = uv_buf_init(base, nread);
18101807

18111808
Isolate* isolate = env()->isolate();
18121809

18131810
// Create an array buffer for the read data. DATA frames will be emitted
18141811
// as slices of this array buffer to avoid having to copy memory.
18151812
stream_buf_ab_ =
18161813
ArrayBuffer::New(isolate,
1817-
buf.base,
1818-
nread,
1819-
ArrayBufferCreationMode::kInternalized);
1814+
base,
1815+
nread,
1816+
ArrayBufferCreationMode::kInternalized);
18201817

18211818
statistics_.data_received += nread;
18221819
ssize_t ret = Write(&stream_buf_, 1);

test/sequential/test-http2-max-session-memory.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const http2 = require('http2');
88

99
// Test that maxSessionMemory Caps work
1010

11-
const largeBuffer = Buffer.alloc(1e6);
11+
const largeBuffer = Buffer.alloc(2e6);
1212

1313
const server = http2.createServer({ maxSessionMemory: 1 });
1414

0 commit comments

Comments
 (0)