-
Notifications
You must be signed in to change notification settings - Fork 49
quic: hopefully avoid memory fragmentation issue #388
quic: hopefully avoid memory fragmentation issue #388
Conversation
Thanks @jasnell. I've cherry-picked built and installed it. I'll aim to leave the hardware running with glibc malloc and your commit over the weekend for report on Monday. |
@jasnell You’re 100 % correct here – |
The |
@jasnell This seems to work well. Currently sitting at 55MB after 3 days. |
@@ -166,7 +166,8 @@ class QuicPacket : public MemoryRetainer { | |||
SET_SELF_SIZE(QuicPacket); | |||
|
|||
private: | |||
std::vector<uint8_t> data_; | |||
uint8_t data_[NGTCP2_MAX_PKTLEN_IPV4]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR message talks about using NGTCP2_MAX_PKT_SIZE
but new code uses NGTCP2_MAX_PKTLEN_IPV4
is that correct? (note that the check in constructor QuicPacket::QuicPacket(const char* diagnostic_label, size_t len)
still checks for NGTCP2_MAX_PKT_SIZE
)
Also, NGTCP2_MAX_PKT_SIZE
recently changed to NGTCP2_DEFAULT_MAX_UDP_PAYLOAD_SIZE
(ngtcp2/ngtcp2@38feb91)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll double check on that. May have mentally mixed those up
Fantastic. Will get this updated in the next day or two and get it landed. |
Closing in favor of nodejs/node#33912 |
Original PR: nodejs/quic#388 Previously, QuicPacket was allocating an std::vector<uint8_t> of NGTCP2_MAX_PKT_SIZE bytes, then the packet would be serialized into the buffer, and the std::vector would be resized based on the number of bytes serialized. I suspect the memory fragmentation that you're seeing is because of those resize operations not freeing memory in chunks that are aligned with the allocation. This changes QuicPacket to use a stack allocation that is always NGTCP2_MAX_PKT_SIZE bytes and the size of the serialized packet is just recorded without any resizing. When the memory is freed now, it should be freed in large enough chunks to cover subsequent allocations. Signed-off-by: James M Snell <jasnell@gmail.com>
Original PR: nodejs/quic#388 Previously, QuicPacket was allocating an std::vector<uint8_t> of NGTCP2_MAX_PKT_SIZE bytes, then the packet would be serialized into the buffer, and the std::vector would be resized based on the number of bytes serialized. I suspect the memory fragmentation that you're seeing is because of those resize operations not freeing memory in chunks that are aligned with the allocation. This changes QuicPacket to use a stack allocation that is always NGTCP2_MAX_PKT_SIZE bytes and the size of the serialized packet is just recorded without any resizing. When the memory is freed now, it should be freed in large enough chunks to cover subsequent allocations. Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #33912 Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Denys Otrishko <shishugi@gmail.com>
@splitice ... I'm hoping this provides a reasonable fix for #386
Previously,
QuicPacket
was allocating anstd::vector<uint8_t>
ofNGTCP2_MAX_PKT_SIZE
bytes, then the packet would be serialized into the buffer, and thestd::vector
would be resized based on the number of bytes serialized. I suspect the memory fragmentation that you're seeing is because of those resize operations not freeing memory in chunks that are aligned with the allocation. This changesQuicPacket
to use a stack allocation that is alwaysNGTCP2_MAX_PKT_SIZE
bytes and the size of the serialized packet is just recorded without any resizing. When the memory is freed now, it should be freed in large enough chunks to cover subsequent allocations.This is the most likely culprit in the current implementation so let me know if this patch fixes it. Will keep this open until I get confirmation from you one way or the other.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes