-
-
Notifications
You must be signed in to change notification settings - Fork 138
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 buf copy and fix buf leak #101
Conversation
Codecov Report
@@ Coverage Diff @@
## master #101 +/- ##
============================================
+ Coverage 78.9% 78.94% +0.03%
Complexity 1011 1011
============================================
Files 258 258
Lines 3655 3661 +6
Branches 487 487
============================================
+ Hits 2884 2890 +6
Misses 531 531
Partials 240 240
Continue to review full report at Codecov.
|
@@ -164,7 +164,9 @@ class MySQLConnectionHandler( | |||
} | |||
ServerMessage.BinaryRow -> { | |||
val m = message as BinaryRowMessage | |||
this.currentQuery!!.addRow(this.binaryRowDecoder.decode(m.buffer, this.currentColumns)) | |||
val decodedRow = this.binaryRowDecoder.decode(m.buffer, this.currentColumns) | |||
m.buffer.release() |
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.
my understanding is you don't need to release the buffer from BytesToMessageDecoder
@@ -222,7 +222,8 @@ class MySQLFrameDecoder(val charset: Charset, private val connectionId: String) | |||
|
|||
return if (this.totalColumns == this.processedColumns) { | |||
if (this.isPreparedStatementExecute) { | |||
val row = slice.readBytes(slice.readableBytes()) | |||
val row = slice.retainedSlice() | |||
slice.readerIndex(slice.readerIndex() + slice.readableBytes()) |
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.
Okay, according to https://netty.io/4.1/api/io/netty/handler/codec/ByteToMessageDecoder.html
Some methods such as ByteBuf.readBytes(int) will cause a memory leak if the returned buffer is not released or added to the out List. Use derived buffers like ByteBuf.readSlice(int) to avoid leaking memory.
we should have this fix, but why not just readSlice? then you don't need to release it in the file above
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.
If not retained, the buf will be released while current handler finished, and cannot be accessed in another handler.
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.
@andy-yx-chen Replaced with readRetainedSlice
.
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.
@jilen you are right, please help to check if there are other places that have the same issue here
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.
@oshai , we need you to take a look at this one, good finding actually
I will review it as soon as possible. I just wonder why this leak wasn't noticed until now. Will also compare it to mauricio. |
thanks, I think the fix is valid, I also read the source code for netty, the readBytes will return a buffer from MessageDecoder's ctx.allocator, which is pooled, and need to be explicitly release |
@jilen Thanks for raising the issue! In addition, the copied buffer was probably leaking. I tried using What I did find is the following:
Would be glad to get more input before merging it. |
@oshai Yes, those bufs could be replaced with |
8c1a8f2
to
cefde94
Compare
again, whether detector reports the leak or not, the fact is readBytes in MessageDecoder will cause leak, as it will allocate a buffer in handler context.alloc, which needs to be release explicitly as the document says |
@jilen Thanks again for the fix! |
No description provided.