【问题标题】:Memory leak on repeated connection/disconnection with reactivesockets使用响应式套接字重复连接/断开连接时的内存泄漏
【发布时间】:2015-12-17 08:29:05
【问题描述】:

我正在使用我在 GitHub (https://github.com/clariuslabs/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 的内存分析器中看到的是,当我运行我的测试应用程序时,服务器的内存使用量呈线性增长。当测试应用停止时,服务器的内存使用量并没有下降;它保持在它达到的任何水平。

当我在没有实例化 StringChannel 类并订阅 Receiver 的代码的情况下运行 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());
  });

  server.Start();

  Console.WriteLine("Press Enter to exit");
  Console.ReadLine();
}

因此,我怀疑内存泄漏可能与客户端断开连接时未正确处理协议接收器的订阅(在执行protocol.Receiver.Subscribe 时)有关。阅读更多有关 Rx.NET 的详细信息,我已经阅读过,在正常情况下(如果可观察序列完成),则订阅会自动处置,但如果序列未完成,则不会处置。我怀疑当客户端断开连接并且订阅未处理时序列未完成。我尝试在 Disconnected 事件处理程序中处理订阅,但没有看到任何明显的改进。

非常感谢任何想法或建议。

谢谢。

【问题讨论】:

    标签: c# sockets memory-leaks reactive-programming rx.net


    【解决方案1】:

    断开连接后尝试添加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");
        }
      }
    }
    

    【讨论】:

    • 你是对的:控制客户端应该被处理掉。但是,内存泄漏发生在服务器中,因此我看不到由于此修复程序的任何改进。
    【解决方案2】:

    我无法解决内存泄漏,所以我决定更换库。我现在使用SuperSocket,效果非常好。完全没有内存问题。

    【讨论】:

    • 我正在为我使用超级套接字服务器上的内存在断开客户端后没有减少事件有什么想法吗?
    猜你喜欢
    • 2012-09-19
    • 1970-01-01
    • 2019-03-05
    • 2021-12-09
    • 2012-09-06
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    相关资源
    最近更新 更多