何时进行对象池?
何时使用 C# 进行对象池?任何好的例子...
维护一个经常使用的对象池并从池中获取一个而不是创建一个新对象有什么优点和缺点?
When to go for object pooling using C#? Any good ex...
What are the pro's and con's of maintaining a pool of frequently used objects and grab one from the pool instead of creating a new one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我能想到的只有两种类型的资源通常是池化的:线程和连接(即数据库)。
两者都有一个首要问题:稀缺。
因此,您想要创建资源池的主要原因是您在任何时候只能负担有限数量的资源。
There are only two types of resources I can think of that are commonly pooled: Threads and Connections (i.e. to a database).
Both of these have one overarching concern: Scarcity.
So the main reason you'd want to create a resource pool is if you can only afford to have a limited number of them at any one time.
我会将内存碎片添加到列表中。当使用封装本机资源的对象时,可能会发生这种情况,这些资源在分配后无法由垃圾收集器移动,并且可能会产生堆碎片。
一个现实生活中的例子是当您创建和销毁大量套接字时。它们用来读/写数据的缓冲区必须被固定才能传输到本机 WinSock API,这意味着当垃圾收集发生时,即使为被破坏的套接字回收了一些内存 - 它可能会留下内存处于碎片状态,因为 GC 无法在收集后压缩堆。因此,读/写缓冲区是池化的主要候选者。另外,如果您使用 SocketEventArgs 对象,那么它们也是不错的选择。
这是好文章,讨论了垃圾收集过程、内存压缩以及对象池为何有用。
I would add memory fragmentation to the list. That can occur when using objects that encapsulate native resources which after they are allocated can not be moved by the Garbage Collector and could potentially fragment the heap.
One real-life example is when you create and destroy lots of sockets. The buffers they use to read/write data have to be pinned in order to be transferred to the native WinSock API which means that when garbage collection occurs, even though some of the memory is reclaimed for the sockets that where destroyed - it could leave the memory in a fragmented state since the GC can't compact the heap after collection. Thus the read/write buffers are prime candidates for pooling. Also, if you're using SocketEventArgs objects, those would also be good candidates.
Here's a good article that talks about the garbage collection process, memory compacting and why object pooling helps.
对于游戏来说,GC 在某些情况下可能会带来不必要的延迟。如果是这种情况,重用对象可能是一个好主意。 此主题中有一些关于该主题的有用注意事项。
For games GC may introduce an unwanted delay in some situations. If this is the case, reusing objects may be a good idea. There's are some useful considerations on the topic in this thread.
有一篇出色的 MSDN 杂志文章,名为“重新发现托管代码中丢失的内存优化艺术”,作者 Erik Brown 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详细解释了大对象堆。
There is an excellent MSDN magazine article called Rediscover the Lost Art of Memory Optimization in Your Managed Code by Erik Brown http://msdn.microsoft.com/en-us/magazine/cc163856.aspx. It includes a general purpose object pool with a test program. This object pool does support minimum and maximum sizes. I can't find any references to people using this in production. Has anyone done so? Also, having dealt with memory fragmentation in an ASP.NET application I can attest to the value in Miky Dinescu's answer. Also, elaborating slightly on Vitaly's answer, consider the case of large objects (i.e. > 85K) which are expensive to create. Large objects only participate in Gen 2 garbage collection. This means that they won't be collected as quickly as objects that fully participate in garbage collection in Gen 0 and Gen 1. This article Large Object Heap Uncovered by Maoni Stephens
at http://msdn.microsoft.com/en-us/magazine/cc534993.aspx explains the large object heap in detail.