Description
Description
For long running scenarios where reads are pending and data is only occasionally sent back and forth, the cost of using SSLStream is high from a memory POV. Today SSL Stream allocates a 8K buffer for the handshake and a 32K buffer per read. It optimizes for reading the TLS header and payload into the same buffer and in the end copies that to the user specified buffer.
Regression?
No
Data
A demo of 5000 websocket connections connected to an ASP.NET Core server using Kestrel:
Here's a heap dump sorted by inclusive size. Most of what is being held onto is array pool buffers.
Allocation profile of 5000 websocket connections. You can see the array pool has the most byte[] allocations.
They're mostly in the handshake and reading (I'm not writing in this app), just sitting mostly idle with ping pongs:
Analysis
We support specifying the buffer size
for SslStream
, much like FileStream, so that the user provided buffer can be used instead of the internal buffer to reduce memory usage. A bufferSize of 1 would signal to the SslStream that the buffer shouldn't be used.
I don't think we need a handshake buffer size...
The problem is SslStream has 5 constructors...
public class SslStream
{
+ public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback, LocalCertificateSelectionCallback? userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy, int bufferSize)
}