简体   繁体   English

C#.NET 3.5:内存池,知道何时释放对象?

[英]C# .NET 3.5: Memory Pool, know when object is released?

I'm in a situation where I'm having to create thousands of objects at once, and the cost of instantiating the objects and garbage collecting them is impacting the performance of the application, and the impact of the garbage collector running hurts the performance more since this is on older hardware, so I'm mostly trying to prevent the creation of garbage. 我处在一种情况下,我必须一次创建数千个对象,实例化这些对象并对其进行垃圾回收的成本影响了应用程序的性能,而垃圾回收器运行的影响更严重地影响了性能。由于这是在较旧的硬件上进行的,因此我主要是在尝试防止垃圾的产生。 I believe a memory pool would solve my issue but I'm not sure how the memory pool would know when a resource in the pool was freed up for re-use. 我相信内存池可以解决我的问题,但是我不确定何时释放池中的资源以供重新使用时,内存池如何知道。 The tricky part is that receiver of objects from the pool end up passing that object around throughout the program and it would be very difficult to know when it could be manually freed up. 棘手的部分是,来自池的对象的接收者最终会在整个程序中传递该对象,并且很难知道何时可以手动释放该对象。 I'd like it to be like a WeakReference , where I could know when nobody was using it anymore. 我希望它像WeakReference ,在那里我可以知道何时没有人使用它。 But my understanding is that if I use a WeakReference in the memory pool then it would eventually get garbage collected from the pool itself and I need these objects to remain pretty much forever so they'll continue to get recycled. 但是我的理解是,如果我在内存池中使用WeakReference ,那么它将最终从池本身中收集垃圾,并且我需要这些对象永远永久保存,以便它们继续被回收。 Sometimes the program can go for awhile without needing the objects so I imagine the garbage collector would collect them before the next time when they were needed and that would then trigger another performance hit as another thousand of these objects were made. 有时程序可以在不需要对象的情况下运行一会儿,所以我想垃圾回收器会在下一次需要它们之前收集它们,然后在制造成千上万个对象时会触发另一个性能下降。

Is there a way I can make sure these objects are never collected, but know when there are no references to them aside from the memory pool itself? 有没有一种方法可以确保这些对象从未被收集,但是除了内存池本身之外,还知道何时没有对它们的引用? Do I need to implement reference counting for these objects somehow? 我是否需要以某种方式实现这些对象的引用计数?

I've been googling for a couple of hours now and have seen no implementation of a Memory Pool that doesn't require the user to let the memory pool know when they're done with it. 我已经搜索了两个小时,并且没有看到没有实现内存池的实现,该实现不需要用户在使用完内存池后就知道。 I find it hard to believe there is no way to do this in C#. 我发现很难相信C#无法做到这一点。

Is there a way I can make sure these objects are never collected, but know when there are no references to them aside from the memory pool itself? 有没有一种方法可以确保这些对象从未被收集,但是除了内存池本身之外,还知道何时没有对它们的引用?

Usually an object pool only holds references to available objects (you can check ObjectPool implementation in Roslyn ). 通常,对象池仅保存对可用对象的引用(您可以在Roslyn中检查ObjectPool实现 )。 With that in mind, you can use the finalizer to resurrect the object and return it to the pool when it is unreachable. 考虑到这一点,您可以使用终结器来复活对象,并在无法访问该对象时将其返回到池中。

However, I don't think it will improve performance. 但是,我认为它不会提高性能。 The whole pool will very soon reach generation 2, so the unreachable objects will need a full garbage collection to be returned to the pool. 整个池很快就会到达第2代,因此无法访问的对象将需要完整的垃圾回收才能返回到池。 Depending on the memory usage pattern in your program, it might not happen very often. 根据程序中的内存使用模式,它可能不会经常发生。 You can GC.Collect() and GC.WaitForPendingFinalizers() of course, but it will also hurt performance. 您当然可以使用GC.Collect()GC.WaitForPendingFinalizers() ,但是这也会影响性能。 You can try it out and check if it helps. 您可以尝试一下并检查是否有帮助。

Another problem is the design - your objects are coupled to the pool. 另一个问题是设计-您的对象已耦合到池中。

I'd rather try to return the objects to the pool explicitly. 我宁愿尝试将对象显式返回到池中。 Remember that not all objects have to be returned. 请记住,并非所有对象都必须返回。 If there are no more available objects, the pool can create new ones. 如果没有更多可用对象,则池可以创建新对象。 The ones that were not returned will just be garbage collected. 没有返回的将被垃圾回收。 Check if there are some code paths where you are sure the objects are not needed anymore. 检查是否有某些代码路径可以确保不再需要这些对象。 If you can't find any, try to refactor your code. 如果找不到,请尝试重构代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM