Artur Hefczyc opened 1 decade ago
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Partially done, some improvements are still possible though. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I reviewed current implementation and I think that current size of input buffer (which reads data from socket and passes to parser or TLS engine for unwrapping) which is set to 2k and may be increased/decreased as needed is OK and should not be changed as smaller size may require frequent resizes which may create additional work for garbage collector. I also checked buffer used by I changed way in which this buffer is resized, so it will be increased if needed but if all data will be read from connection (no data waiting) then it will be resized down to default value. I also changed default size for this buffer. Now it will be equal to minimal from network socket buffer (2k for client connections and 64k for HT connections) and Due to above changes we should reduce memory usage by tlsInput buffer from 16k to 2k for typical XMPP client with TLS/SSL and possible we can get even bigger reduction if client sent to server big packets as this could increate tlsInput buffer which was never resized to smaller value. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Thank you for looking into it. I was aware that the current data buffer size is 2k and default TLS/SSL buffer size is 16k. In fact the standard TLS/SSL buffer size across different systems is 16k and sometimes is bigger. Normally it is not even possible to correctly read and decipher TLS/SSL data form a stream with smaller than 16k buffers. However, normally for the XMPP systems a connection is idle for most of the time, therefore, 16k for a buffer which is not used looks like a waste of memory. Especially if we have a system with 200k+ connections, most of them idle most of the time and only occasionally sending some data. It's like over 3GB of RAM wasted. And for large chunks of data the TLS buffer size easily gets much larger. So my intention for the task was to do the following:
From your description it looks like you made it work exactly like this. Please confirm if this is the case and close the ticket. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I tried with Psi+ and Tigase XMPP Server with buffer set to 2k and data was correctly read and deciphered by TLS using this small buffer - needed to resize it only if there were more data in single TCP/TLS frame. So I think it is possible. Yes, I did what you intended to be done in this task. Now If connection is idle TLS buffer and input buffer will be resized to 2k, and resized to bigger size only when needed. However before I close this task I wonder if we should not change algorithm responsible for resizing buffers to bigger size - as now size is increased by 2k every time. I think that now, when we reduce size as well we could (and should) change it to use new algorithm by increasing buffer size by half of existing buffer size. It could use more memory than needed but in fact it could allocate less memory in process. Current algorithm:
Suggested new algorithm:
In case of required buffer of size 31k (during VCard publication I got similar size) we would have following results:
From that you can see that use of ratio based resizing of input buffer than constant based could reduce number of memory allocations and could reduce number of objects for GC, but may result in temporary increase of memory usage as buffer size should be reduced just after connection will become idle. I think that we should use ratio based resizing with ratio set to 1.5 or maybe bigger, however bigger ration will be responsible for faster increase of size of buffer and may lead to wasting memory in this buffer as not whole buffer will be used (but only for a short time). %kobit What do you think? |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Andrzej Wójcik wrote:
I think this is a very good idea. I definitely like using the new algorithm. However, I think a better ration would be 2 instead of 1.5. In your example above it would allocate 32kB faster and would waste less memory. So higher ratio does not always mean more wasted memory. Moreover, more iterations to allocate buffer to required size mean actually more wasted memory because there is more objects for GC to deal with. So I think bigger ratio gives us more benefits than disadvantages. It kind of surprises me what you say about 2k buffer being enough for TLS. I believe you of course, I just remember that I could not get below 16kB which appeared to be minimal possible and also all TLS buffer size increases were multiplication of 16. So, if 16kB was too small, I had to resize it to 32kB, then to 48kB, and so on... Maybe it also depends what kind of software works on the other side of the TLS stream.... Also my tests were run quite a few years ago, different OS, different Java version. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
%kobit Ok, will use 2 as ratio for resizing buffers - for that I created separate task #4111 As for TLS required buffer size it depends on implementations of TLS on both sides, stream flushing, used ciphers and used TLS protocol - now we have TLSv1.1 and TLSv1.2, while not so long ago there was only TLSv1.0 and SSLv3. However even if it would occur that it needs to be resized for some reason every time this new solution will handle this and work fine. |
Type |
Task
|
Priority |
Minor
|
Assignee | |
RedmineID |
14
|
Version |
tigase-server-8.0.0
|
Estimation |
16h
|
Spent time |
33h
|
Currently TLS buffers are resized down to the default TLS buffer capacity. However, for clients connections, which are idle for most of the time this leads to wasting lots of memory in buffers which are not used anyway. Resizing them down to even unusable size might be a better approach, as in XMPP c2s connection is not used for most of the time, so it does not really matter if we sometimes have to resize them back to a bigger size when data comes.