预先分配 SocketAsyncEventArgs 对象池如何提高 C# 中服务器应用程序的性能

问题描述 投票:0回答:1

在服务器应用程序中,有效管理传入连接对于实现最佳性能至关重要。我遇到了 TCP 套接字编程中使用的常见优化技术,如 Microsoft 的代码示例中所示,其中涉及在服务器启动之前预先创建 SocketAsyncEventArgs 对象池,

代码示例

如代码示例所示,此方法旨在通过预分配固定数量的 SocketAsyncEventArgs 对象来提高服务器性能。然后,通过重用这些对象来处理传入连接,而无需重新创建。 然而,我很难理解这种技术如何真正提高性能。让我们考虑一个场景,其中服务器设计为最多处理 10 个同时连接,

在创建服务器之前,会初始化 10 个 SocketAsyncEventArgs 对象的池并将其添加到池中。虽然这允许重用对象而无需不断创建和销毁,但它存在局限性。例如,如果服务器只有 5 个连接的客户端, 那么池中剩余的 5 个 SocketAsyncEventArgs 对象未使用,这就提出了一个问题:预分配固定的对象池是否会限制可扩展性和资源利用率?

如果您考虑一下,另一种方法可能涉及在接受连接时动态创建 SocketAsyncEventArgs 对象, 对于每个新的客户端连接,都会实例化一个新的 SocketAsyncEventArgs 对象并与客户端会话关联。这种方法通过仅按需创建对象来避免预分配约束并优化资源使用。,

考虑到这一点,如果服务器有最大连接数,这两种方法似乎都会利用相同数量的资源来创建 SocketAsyncEventArgs 对象,

在第一种方法中,预先创建固定数量的对象, 而在第二种方法中,对象是按需创建的,鉴于此,与按需动态创建对象相比,预分配固定的 SocketAsyncEventArgs 对象池如何提高性能?

谢谢你。

只是一些方法的问题

c# .net sockets memory-management tcp
1个回答
0
投票

预分配固定的对象池是否会限制可扩展性和资源利用率?

有时它至少会浪费一些内存。是否对可扩展性施加任何实际限制将取决于具体的实现和用例。我缺乏经验来判断在这种特定情况下这是否是一个实际问题。

如果您考虑一下,另一种方法可能涉及在接受连接时动态创建 SocketAsyncEventArgs 对象,对于每个新的客户端连接,都会实例化一个新的 SocketAsyncEventArgs 对象并与客户端会话关联。这种方法通过仅按需创建对象来避免预分配约束并优化资源使用。,

您需要考虑在连接关闭时是否以及何时应该释放对象。随着需求的减少,某些类型的池的大小会缓慢减小。其他人可能会永远保留分配的资源。

在第一种方法中,预先创建固定数量的对象,而在第二种方法中,按需创建对象,鉴于此,与按需动态创建对象相比,预分配固定的 SocketAsyncEventArgs 对象池如何提高性能?

一次分配多个对象可以帮助将对象按顺序保留在内存中,这可能有助于缓存的使用。一次分配多个而不是一次分配一个可能会稍微快一些。

但我认为更大的问题是复杂性和权衡之一。固定大小的池比动态池复杂。如果固定的工作足够好,为什么还要花时间去开发、分析和测试更复杂的东西呢?并记住机会成本,即使值得做,它是花费有限资源的“最好”的事情吗?这与优化黄金法则相关,即仅将有限的资源用于优化真正重要的事情。

© www.soinside.com 2019 - 2024. All rights reserved.