定制的内存分配器或内存池

4

我正在使用第三方网络库,并且为了发送网络消息,我需要创建一个新的 NetworkMessage 类实例。这是效率很低的,因为应用程序需要非常快速地运行,并且有很多消息传递,所以我正在寻找一种避免为每个消息动态分配内存的方法。

如果 NetworkMessage 是一个结构体,则我们不会有问题。但是,我不能存储预先创建的 NetworkMessage 实例,因为消息参数只能在构造函数中传递,并且后续不能更改。由于这是一个第三方类,因此我无法更改 NetworkMessage 类中的任何内容。

有没有办法在 C# 中创建内存池,然后使用类似于 C ++ 的 placement new 运算符从该池中创建对象?(我知道 C# 中没有 placement new 运算符)。我正在寻找一种初始化内存块,然后使用该内存块的块来创建 NetworkMessage 类实例的方法。


6
你是否实际测量过,确认这个分配问题导致了减速?.Net 的分配器和 GC 已经针对“大量小的短生命周期对象”进行了优化。如果你只是猜测,那么你很可能是错的。 - Adam Wright
正如其他人所说,你确定这是你的瓶颈吗?NetworkMessage看起来像什么?它是sealed的吗? - svick
兄弟,那就是dotNet垃圾回收堆。你已经在做了。 - Ben
感谢大家的评论。你们说得对,我还不确定这是否会成为瓶颈,因为我们还处于早期开发阶段。这只是未来的一个想法,以防它成为瓶颈,并且由于我来自C++背景,我不知道在C#中内存分配对于微小的短暂对象是如此优化的。所以我想这不会成为问题。我担心的是每分钟将创建数千条消息。 - sirival
2个回答

1

在我们继续之前,有一点需要说明:在.NET中,内存分配非常高效。它不像在COM中那样是一个昂贵的操作。

话虽如此,我看到了两种解决方案:

你可以简单地创建一个NetworkMessage实例池,然后使用一个简单的管理器类从池中获取并释放它们。

另一种选择是使用反转控制容器,例如Castle WindsorUnityNInject。这些容器为您处理依赖项创建和对象生命周期管理。

祝你好运!


我认为这里不适合使用对象池,因为参数只有在需要消息时才能确定,并且它们必须传递给构造函数。我也想不出 IoC 如何对性能产生任何影响。 - svick
谢谢您的回复。正如我之前所说,我不知道C#对于小型动态分配是如此优化! - sirival
希望投反对票的人能够给出下降的动机! - Roy Dictus
对于需要分配大量小对象的性能关键应用程序来说,它仍然太慢了。 - apen

1

NetworkMessage在构造函数中需要哪些输入参数?

它需要一个字节数组吗?如果是这样,那么这将是一个更好的候选对象,而不是NetworkMessage类本身。

微软有一个Networking Sample,演示了如何在示例异步套接字服务器中池化大型字节数组。


这是一个很好的观点 - 这个类的参数是键值对对象,可以预先在对象池中创建,因此如果内存分配实际上成为问题,我一定会考虑这样做! - sirival

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接