使用c#和SSH在SSH上传输/跟踪数据.. NET泄漏内存

本文关键字:SSH 数据 跟踪 NET 泄漏 内存 传输 使用 | 更新日期: 2023-09-27 17:52:43

我正在尝试使用c#通过SSH跟踪文件。从一开始就读取这个文件,然后每次持续监视几个小时,以保持SSH连接。我正在使用SSH。. NET库为SSH提供功能。文件大小可以在任何地方,最高可达2GB。当前的实现正在工作,但是内存使用非常糟糕。

测试:为了测试这个功能,我使用Visual Studio 2012,目标是。net框架4.5,用下面的代码创建一个小的控制台应用程序。我正在跟踪一个静态文件,大约127MB。

问题:从功能上讲,这工作得很好,但内存使用相当糟糕。在调用shellStream.WriteLine之前,应用程序将使用~7MB,然后快速增加并稳定使用~144MB(当从流中读取所有当前文件内容时稳定)。

下面是我要使用的代码。

private SshClient sshClient;
private ShellStream shellStream;
//Command being executed to tail a file.
private readonly string command = "tail -f -n+1 {0}";
//EventHandler that is called when new data is received.
public EventHandler<string> DataReceived;
public void TailFile(string server, int port, string userName, string password, string file)
{
   sshClient = new SshClient(server, port, userName, password);
   sshClient.Connect();
   shellStream = sshClient.CreateShellStream("Tail", 0, 0, 0, 0, 1024);
   shellStream.DataReceived += (sender, dataEvent) =>
   {
      if (DataReceived != null)
      {
         DataReceived(this, Encoding.Default.GetString(dataEvent.Data));
      }
   };
   shellStream.WriteLine(string.Format(command, file));
}

是否缺少一些东西来防止内存增加,或者有其他解决方案可以实现相同的目标?

使用c#和SSH在SSH上传输/跟踪数据.. NET泄漏内存

您不使用流中的数据,因此它会累积。

查看如何实现ShellStream.DataReceived事件:

private void Channel_DataReceived(object sender, ChannelDataEventArgs e)
{
    lock (this._incoming)
    {
        // this is where the memory "leaks" as the _incoming is never consumed
        foreach (var b in e.Data)
            this._incoming.Enqueue(b);
    }
    if (_dataReceived != null)
        _dataReceived.Set();
    this.OnDataReceived(e.Data);
}

不使用ShellDataEventArgs.Data,使用ShellStream.Read:

 shellStream.DataReceived += (sender, dataEvent) =>
 {
    if (DataReceived != null)
    {
       DataReceived(this, shellStream.Read());
    }
 };