rsocket-java
rsocket-java copied to clipboard
CompositeByteBuf memory allocation for Frame messages
Motivation
I have been evaluating the RSocket and did some profiling. It looks like creating Frame message many ByteBuf
buffers are used (i.e. header, payload, frame size). Those buffers are composed using CompositeByteBuf
. The ByteBuf
can be reused, but the CompositeByteBuf
are always created as new ones. Such CompositeByteBuf
allocation doesn't take much memory, but sending many Frame messages it sums up. Here is an example memory allocation using async-profiler:
![CleanShot 2022-09-05 at 15 39 01@2x](https://user-images.githubusercontent.com/3429466/188467223-e91d8686-4c81-4189-ac60-47a8a1f9550b.png)
Also when Netty sends the Frame messages it needs to duplicate internal DirectByteBuffer
objects because of CompositeByteBuf
usage:
![CleanShot 2022-09-05 at 16 31 51@2x](https://user-images.githubusercontent.com/3429466/188472239-ffbb3479-9e45-4221-9de7-dbfc9b6e48c2.png)
This wouldn't be the case if only one ByteBuf
were used instead.
As far as I understand, it is done in order to avoid copying buffers. Nevertheless maybe there is a way of improving it?
Considered alternatives
Alternatives would be:
- avoid using
CompositeByteBuf
and just use oneByteBuf
per Frame message. - provide a way of customize the creation of Frame messages. Current implementation is using static
SendUtils.sendReleasingPayload()
method and there is no way of replacing it.
Additional context
I'm using rsocket-java
version 1.1.2
with TCP
transport.
@agusevas thanks for your investigation!
I think the best way to go is to create a similar issue at the netty project and reference this one! We can contribute to netty if needed