什么时候进行对象池?

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

何时使用 C# 进行对象池?有什么好的前任吗...

维护一个经常使用的对象池并从池中获取一个而不是创建一个新对象有什么优点和缺点?

c# memory-management object pooling
5个回答
5
投票

我能想到的只有两种类型的资源通常被池化:线程和连接(即数据库)。

两者都有一个首要关注点:稀缺性。

  • 如果创建太多线程,上下文切换将浪费所有 CPU 时间。
  • 如果创建太多网络连接,维护这些连接的开销就会变得比连接应该做的事情更多。
  • 此外,对于数据库,由于许可原因,连接数可能会受到限制。

因此,您想要创建资源池的主要原因是您在任何时候只能拥有有限数量的资源。


5
投票

我会将“内存碎片”添加到列表中。当使用封装本机资源的对象时,可能会发生这种情况,这些资源在分配后无法由垃圾收集器移动,并且可能会导致堆碎片。 一个现实生活中的例子是当您创建和销毁大量套接字时。它们用来读/写数据的缓冲区必须被固定才能传输到本机 WinSock API,这意味着当垃圾收集发生时,即使为被破坏的套接字回收了一些内存 - 它可能会留下内存处于碎片状态,因为 GC 无法在收集后压缩堆。因此,读/写缓冲区是池化的主要候选者。另外,如果您使用 SocketEventArgs 对象,那么它们也是不错的选择。

这里有一篇

好文章

,讨论了垃圾收集过程、内存压缩以及为什么对象池有帮助。


4
投票
当对象创建成本高昂时
  1. 当您可能遇到内存压力时 - 太多的对象(例如 - 享元模式)

1
投票
this thread

中有一些关于该主题的有用注意事项。


0
投票
http://msdn.microsoft.com/en-us/magazine/cc163856.aspx

。它包括一个带有测试程序的通用对象池。该对象池确实支持最小和最大大小。我找不到任何在生产中使用它的人的参考资料。有人这样做过吗?另外,在处理 ASP.NET 应用程序中的内存碎片后,我可以证明 Miky Dinescu 的答案的价值。另外,稍微阐述一下 Vitaly 的答案,考虑创建成本高昂的大型对象(即 > 85K)的情况。大对象仅参与 Gen 2 垃圾回收。这意味着它们的收集速度不会像第 0 代和第 1 代中完全参与垃圾收集的对象那样快。本文《大对象堆》由 Maoni Stephens 揭秘 在 http://msdn.microsoft.com/en-us/magazine/cc534993.aspx 详细解释了大对象堆。

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