使用 reactivesockets 重复 connection/disconnection 时内存泄漏
Memory leak on repeated connection/disconnection with reactivesockets
我正在使用在 GitHub (https://github.com/clariuslabs/reactivesockets) 中找到的 reactivesockets 库,我想知道是否有人在客户端连接和断开连接时遇到内存泄漏。
我正在 运行使用库随附的 ReactiveServer 示例,它主要包括:
static void Main(string[] args)
{
var port = 1055;
if (args.Length > 0)
port = int.Parse(args[0]);
var server = new ReactiveListener(port);
server.Connections.Subscribe(socket =>
{
Console.WriteLine("New socket connected {0}", socket.GetHashCode());
var protocol = new StringChannel(socket);
// Here we hook the "echo" prototocol
protocol.Receiver.Subscribe(
s => { Console.Write(s); protocol.SendAsync(s).Wait(); },
e => Console.WriteLine(e),
() => Console.WriteLine("Socket receiver completed"));
socket.Disconnected += (sender, e) => Console.WriteLine("Socket disconnected {0}", sender.GetHashCode());
socket.Disposed += (sender, e) => Console.WriteLine("Socket disposed {0}", sender.GetHashCode());
});
server.Start();
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
然后我创建了一个带有循环的控制台应用程序,并在这个循环中创建了一个 ReactiveClient,然后连接到服务器,等待 200 毫秒,然后断开连接。客户端不向服务器发送任何数据。这是代码:
static void Main(string[] args) {
var numberOfClients = 1000;
for (var i = 0; i < numberOfClients; i++) {
var controlClient = new ReactiveClient("127.0.0.1", 1055);
controlClient.ConnectAsync().Wait();
Console.WriteLine(@"Connect");
Task.Delay(200).Wait();
controlClient.Disconnect();
Console.WriteLine(@"Disconnect");
}
}
我在 Visual Studio 的内存分析器中看到的是,当我 运行 我的测试应用程序时,服务器的内存使用量呈线性增长。测试应用停止时,服务器内存占用不下降;它保持在它达到的任何水平。
当我 运行 ReactiveServer 示例没有实例化 StringChannel 的代码时,内存泄漏似乎没有发生(或者至少没有那么明显,内存使用量呈线性增长)class并订阅接收器。代码将是这样的:
static void Main(string[] args) {
var port = 1055;
if (args.Length > 0)
port = int.Parse(args[0]);
var server = new ReactiveListener(port);
server.Connections.Subscribe(socket =>
{
Console.WriteLine("New socket connected {0}", socket.GetHashCode());
});
server.Start();
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
出于这个原因,我怀疑内存泄漏可能与以下事实有关:当客户端断开连接时,对协议接收器的订阅(在执行 protocol.Receiver.Subscribe
时)未正确处理。详细阅读 Rx.NET,我读到在正常情况下(如果可观察序列完成),订阅会自动处理,但如果序列未完成,则不会处理。我怀疑当客户端断开连接然后订阅没有被处理时,序列没有完成。我尝试在 Disconnected 事件处理程序中处理订阅,但我没有看到任何明显的改进。
非常感谢任何想法或建议。
谢谢。
断开连接后尝试添加 controlClient.dispose();
。
这将释放该对象使用的所有操作资源。
为了让它更好读,我会尝试将 controlClient 包装在一个 using 块中。
static void Main(string[] args) {
var numberOfClients = 1000;
for (var i = 0; i < numberOfClients; i++) {
using{var controlClient = new ReactiveClient("127.0.0.1", 1055))
{
controlClient.ConnectAsync().Wait();
Console.WriteLine(@"Connect");
Task.Delay(200).Wait();
controlClient.Disconnect();
Console.WriteLine(@"Disconnect");
}
}
}
我无法解决内存泄漏问题,所以我决定更换库。我现在正在使用 SuperSocket 并且效果非常好。完全没有内存问题。
我正在使用在 GitHub (https://github.com/clariuslabs/reactivesockets) 中找到的 reactivesockets 库,我想知道是否有人在客户端连接和断开连接时遇到内存泄漏。
我正在 运行使用库随附的 ReactiveServer 示例,它主要包括:
static void Main(string[] args)
{
var port = 1055;
if (args.Length > 0)
port = int.Parse(args[0]);
var server = new ReactiveListener(port);
server.Connections.Subscribe(socket =>
{
Console.WriteLine("New socket connected {0}", socket.GetHashCode());
var protocol = new StringChannel(socket);
// Here we hook the "echo" prototocol
protocol.Receiver.Subscribe(
s => { Console.Write(s); protocol.SendAsync(s).Wait(); },
e => Console.WriteLine(e),
() => Console.WriteLine("Socket receiver completed"));
socket.Disconnected += (sender, e) => Console.WriteLine("Socket disconnected {0}", sender.GetHashCode());
socket.Disposed += (sender, e) => Console.WriteLine("Socket disposed {0}", sender.GetHashCode());
});
server.Start();
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
然后我创建了一个带有循环的控制台应用程序,并在这个循环中创建了一个 ReactiveClient,然后连接到服务器,等待 200 毫秒,然后断开连接。客户端不向服务器发送任何数据。这是代码:
static void Main(string[] args) {
var numberOfClients = 1000;
for (var i = 0; i < numberOfClients; i++) {
var controlClient = new ReactiveClient("127.0.0.1", 1055);
controlClient.ConnectAsync().Wait();
Console.WriteLine(@"Connect");
Task.Delay(200).Wait();
controlClient.Disconnect();
Console.WriteLine(@"Disconnect");
}
}
我在 Visual Studio 的内存分析器中看到的是,当我 运行 我的测试应用程序时,服务器的内存使用量呈线性增长。测试应用停止时,服务器内存占用不下降;它保持在它达到的任何水平。
当我 运行 ReactiveServer 示例没有实例化 StringChannel 的代码时,内存泄漏似乎没有发生(或者至少没有那么明显,内存使用量呈线性增长)class并订阅接收器。代码将是这样的:
static void Main(string[] args) {
var port = 1055;
if (args.Length > 0)
port = int.Parse(args[0]);
var server = new ReactiveListener(port);
server.Connections.Subscribe(socket =>
{
Console.WriteLine("New socket connected {0}", socket.GetHashCode());
});
server.Start();
Console.WriteLine("Press Enter to exit");
Console.ReadLine();
}
出于这个原因,我怀疑内存泄漏可能与以下事实有关:当客户端断开连接时,对协议接收器的订阅(在执行 protocol.Receiver.Subscribe
时)未正确处理。详细阅读 Rx.NET,我读到在正常情况下(如果可观察序列完成),订阅会自动处理,但如果序列未完成,则不会处理。我怀疑当客户端断开连接然后订阅没有被处理时,序列没有完成。我尝试在 Disconnected 事件处理程序中处理订阅,但我没有看到任何明显的改进。
非常感谢任何想法或建议。
谢谢。
断开连接后尝试添加 controlClient.dispose();
。
这将释放该对象使用的所有操作资源。
为了让它更好读,我会尝试将 controlClient 包装在一个 using 块中。
static void Main(string[] args) {
var numberOfClients = 1000;
for (var i = 0; i < numberOfClients; i++) {
using{var controlClient = new ReactiveClient("127.0.0.1", 1055))
{
controlClient.ConnectAsync().Wait();
Console.WriteLine(@"Connect");
Task.Delay(200).Wait();
controlClient.Disconnect();
Console.WriteLine(@"Disconnect");
}
}
}
我无法解决内存泄漏问题,所以我决定更换库。我现在正在使用 SuperSocket 并且效果非常好。完全没有内存问题。