[jboss-jira] [JBoss JIRA] (JGRP-1998) Transport: reuse of incoming buffers

Bela Ban (JIRA) issues at jboss.org
Mon Dec 21 03:27:00 EST 2015


    [ https://issues.jboss.org/browse/JGRP-1998?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13142837#comment-13142837 ] 

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)


More information about the jboss-jira mailing list