SSH.NET icon indicating copy to clipboard operation
SSH.NET copied to clipboard

Memory Leak Issue When Streaming Data Over SSH

Open hossein-mohseni opened this issue 8 months ago • 6 comments

Hello Renci.SshNet Team,

I have encountered a memory leak issue when utilizing the library to stream data over SSH in a .NET application. The memory consumption of the application significantly increases over time and does not get released back, even after the SSH connection is closed and disposed of.

Environment:

Renci.SshNet Version: 2023 , 2020.1 ,2020.2 .NET Version: 7 Steps to Reproduce:

Establish an SSH connection and create a shell stream. Write a command to the shell stream and continuously read the output. Monitor the memory usage of the application. Expected Behavior: Memory should be released back once the data is read from the SSH stream and especially after the SSH client is disconnected and disposed of.

Actual Behavior: Memory usage continuously increases as data is read from the SSH stream and is not released back after the SSH client is disposed of.

Code Sample:

csharp

static async Task<bool> CheckIfLinuxAsync(string[] parts)
{
    string sshIp = parts[0];
    if (!int.TryParse(parts[1], out int sshPort) || sshPort <= 0 || sshPort > 65535)
    {
        return false;
    }
    string username = parts[2];
    string password = parts[3];
    string sshKey = $"{sshIp}:{sshPort}:{username}:{password}";

    try
    {
        var client = _sshClients.GetOrAdd(sshKey, key =>
        {
            var sshClient = new SshClient(sshIp, sshPort, username, password);
            sshClient.ConnectionInfo.Timeout = TimeSpan.FromSeconds(5);
            sshClient.Connect();
            return sshClient;
        });

        if (!client.IsConnected)
        {
            client.Connect();
        }

        using (var command = client.CreateCommand("uname -a"))
        {
            await Task.Run(() => command.Execute()).ConfigureAwait(false);
            return command.Result.Contains("Linux", StringComparison.OrdinalIgnoreCase);
        }
    }
    catch
    {
        _sshClients.TryRemove(sshKey, out var clientToRemove);
        clientToRemove?.Dispose();
        return false;
    }

Profiling Details:

The application's memory usage increases significantly over time. The memory does not get reclaimed even after disconnecting and disposing of the SSH client.

Attachments:

Screenshot 2023-10-12 172504 Screenshot 2023-10-12 172833 Screenshot 2023-10-12 172526 Screenshot 2023-10-12 172543 Screenshot 2023-10-12 172626

Additional Context: This issue is critical for our use case where the application needs to run for extended periods, streaming data over SSH. The memory leak leads to increased resource usage and can eventually cause the application to run out of memory.

Any insights or workarounds would be greatly appreciated while this issue is being investigated and resolved.

Thank you for your time and assistance!

hossein-mohseni avatar Oct 12 '23 14:10 hossein-mohseni