我正在尝试使用C#在SSH上拖尾文件。此文件从头开始读取,然后继续监视几个小时,同时保持SSH连接。我正在使用SSH.NET库来为SSH提供功能。文件大小可以高达~2GB。当前的实现正在运行,但内存使用情况非常糟糕。
测试:为了测试此功能,我使用面向.NET framework 4.5的Visual Studio 2012,使用下面的代码创建一个小型控制台应用程序。我正在拖尾一个大约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));
}
是否有某些东西缺失以防止内存增加,或者任何其他可以实现相同目标的解决方案?
答案 0 :(得分:2)
您不会使用流中的数据,因此会累积。
请参阅how the ShellStream.DataReceived
event is implemented:
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());
}
};