[
https://issues.jboss.org/browse/JGRP-1998?page=com.atlassian.jira.plugin....
]
Bela Ban edited comment on JGRP-1998 at 12/21/15 3:26 AM:
----------------------------------------------------------
h3. UDP
* The same buffer (66000 bytes) is reused
* Message batches are de-serialized off of the UDP buffer and passed to a thread pool for
further processing. *No copy*
* Single messages: the buffer is copied and passed to the thread pool where
de-serialization happens
** If we made processing of single messsages similar to that of message batches, we could
get rid of the buffer copy: do the de-serialization directly in the {{TP.receive()}}
method and pass the message to the thread pool for further processing
*** Look at whether this hampers performance
*** Should not be the case as we're already de-serializing message batches in the
{{TP.receive()}} method
*** Most of the time (when receiving a lot of messages), messages will be received as
message batches, not single messages anyway, so de-serialization of single messages
shouldn't matter (perf-wise)
h3. TCP
* Every connection creates a new buffer for *every* incoming message, based on the length
which is sent first
* I think we can safely switch to reusable buffers as both single message and message
batches get de-serialized in {{TP.receive()}} and therefore implicitly already make a
copy.
** Alternative 1: every {{TcpConnection}} has its own buffer. On reception of {{length}},
if the buffer is too small, we grow it. Downside: large buffers tend to hang around.
Upside: idle connections are reaped, gc'ing the buffer. Also, buffer sizes are never
more than {{TP.max_bundle_size}} (plus some constant overhead) anyway. The other downside
is that we keep 1 buffer per connection, which means {{buffer-size * members}} overhead;
not nice in a large cluster...
** Alterntive 2: use a *buffer pool*. Buffers are only used for a brief period of time: to
de-serialize single messages or message batches. A fixed-size pool might be a more memory
efficient solution, especially in large clusters. On reception of {{length}}, a connection
grabs a right-sized buffer from the pool and returns it after de-serialization and passing
of the de-serialized message to a thread pool. When the buffer is exhausted, a new temp
buffer will be created.
h3. TCP_NIO2
* Every connection has a {{Buffers}} instance for reading. On reception of {{length}}, a
new buffer for the message is created.
* Similar to TCP, we could hang on to that buffer and grow it if needed, or use a buffer
pool (see above)
was (Author: belaban):
h3. UDP
* The same buffer (66000 bytes) is reused
* Message batches are de-serialized off of the UDP buffer and passed to a thread pool for
further processing. *No copy*
* Single messages: the buffer is copied and passed to the thread pool where
de-serialization happens
** If we made processing of single messsages similar to that of message batches, we could
get rid of the buffer copy: do the de-serialization directly in the {{TP.receive()}}
method and pass the message to the thread pool for further processing
*** Look at whether this hampers performance
*** Should nt be the case as we're already de-serializing message batches in the
{{TP.receive()}} method
*** Most of the time (when receiving a lot of messages), messages will be received as
message batches, not single messages anyway, so de-serialization of single messages
shouldn't matter (perf-wise)
h3. TCP
* Every connection creates a new buffer for *every* incoming message, based on the length
which is sent first
* I think we can safely switch to reusable buffers as both single message and message
batches get de-serialized in {{TP.receive()}} and therefore implicitly already make a
copy.
** Alternative 1: every {{TcpConnection}} has its own buffer. On reception of {{length}},
if the buffer is too small, we grow it. Downside: large buffers tend to hang around.
Upside: idle connections are reaped, gc'ing the buffer. Also, buffer sizes are never
more than {{TP.max_bundle_size}} (plus some constant overhead) anyway. The other downside
is that we keep 1 buffer per connection, which means {{buffer-size * members}} overhead;
not nice in a large cluster...
** Alterntive 2: use a *buffer pool*. Buffers are only used for a brief period of time: to
de-serialize single messages or message batches. A fixed-size pool might be a more memory
efficient solution, especially in large clusters. On reception of {{length}}, a connection
grabs a right-sized buffer from the pool and returns it after de-serialization and passing
of the de-serialized message to a thread pool. When the buffer is exhausted, a new temp
buffer will be created.
h3. TCP_NIO2
* Every connection has a {{Buffers}} instance for reading. On reception of {{length}}, a
new buffer for the message is created.
* Similar to TCP, we could hang on to that buffer and grow it if needed, or use a buffer
pool (see above)
Transport: reuse of incoming buffers
------------------------------------
Key: JGRP-1998
URL:
https://issues.jboss.org/browse/JGRP-1998
Project: JGroups
Issue Type: Enhancement
Reporter: Bela Ban
Assignee: Bela Ban
Fix For: 3.6.7
Investigate whether buffers can be reused on the receive side. JGRP-1989 already provides
this on the send side. Goal: reduction of memory allocation rate.
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)