-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Avoid large allocations of temporary buffers in BuferUtil #5045
Avoid large allocations of temporary buffers in BuferUtil #5045
Conversation
Signed-off-by: Sergey Tselovalnikov <[email protected]>
f2f451e
to
1554768
Compare
Thanks for this. I'm reviewing now. |
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.
This is a good simple improvement. However I am concerned that this method is being called frequently enough with a direct buffer to cause a noticeable memory issue. A better way would be to use the direct buffer directly, or not make it a direct buffer in the first place! So we can accept this change, but more work to be done here.
byte[] bytes = null; | ||
while (buffer.hasRemaining()) | ||
{ | ||
int byteCountToWrite = Math.min(buffer.remaining(), TEMP_BUFFER_SIZE); | ||
if (bytes == null) | ||
bytes = new byte[byteCountToWrite]; |
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.
Actually slight change would be better. No need to assign the buffer in the loop:
byte[] bytes = null; | |
while (buffer.hasRemaining()) | |
{ | |
int byteCountToWrite = Math.min(buffer.remaining(), TEMP_BUFFER_SIZE); | |
if (bytes == null) | |
bytes = new byte[byteCountToWrite]; | |
byte[] bytes = new byte[Math.min(buffer.remaining(), TEMP_BUFFER_SIZE)]; | |
while (buffer.hasRemaining()) | |
{ |
@sbordet @lorban , The HttpContentRangeWriter is preferring a direct buffer, but ByteBufferRangeWriter always does a writeTo, causing a copy to a temp buffer. This is a very suboptimal approach! |
Signed-off-by: Sergey Tselovalnikov <[email protected]>
Hey, @gregw! Thank you for the review, the feedback is addressed in 99d1926 as suggested.
You might have already found out, but it's called from |
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.
LGTM - although we will still review in #5048
Thanks for merging! Do I need to open a separate PR into the |
@SerCeMan I'll merge through to 10, then 11 |
Hi, Jetty Maintainers!
We have recently noticed that our jetty instances suffer from a large number of young GC pauses. The allocation profiler pointed out that a large number of allocations is occurring in
BufferUtil#writeTo
.In our use-case, we're receiving a large number of WebSocket messages from many connections but most of them are very small, typically tiny keep-alive frames. The change in this PR can help to avoid allocating 4K temporary arrays when only a few bytes need to be copied. This could potentially be optimised even further with a specialised implementation for
o.e.j.u.ByteArrayOutputStream2
, however, the change won't be as simple.Additionally, I ran
o.e.j.u.BufferUtilTest#testWriteToMicrobenchmark
withcapacity = 1024, iterations = 1000
and it showed a measurable difference in the number of young gc cycles.Before:
After:
As a reference, previous a similar change was introduced in #4561. I'm also happy to open a separate PR for the
10.0.x
branch if it sounds good to you.