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

本文关键字:对象 何时 释放 NET 内存 | 更新日期: 2023-09-27 18:19:41

我不得不同时创建数千个对象,实例化对象和垃圾收集对象的成本正在影响应用程序的性能,而垃圾收集器运行的影响对性能的影响更大,因为这是在较旧的硬件上,所以我主要试图防止垃圾的创建。我相信内存池可以解决我的问题,但我不确定内存池如何知道池中的资源何时被释放以供重用。棘手的部分是,池中对象的接收者最终会在整个程序中传递该对象,并且很难知道何时可以手动释放该对象。我希望它像WeakReference一样,在那里我可以知道什么时候没有人再使用它了。但我的理解是,如果我在内存池中使用WeakReference,那么它最终会从池本身收集垃圾,我需要这些对象永远保留下来,这样它们就会继续被回收。有时程序可以在不需要对象的情况下运行一段时间,所以我想垃圾收集器会在下一次需要对象之前收集它们,然后随着另外一千个对象的生成,这将触发另一个性能打击。

有没有一种方法可以确保这些对象永远不会被收集,但知道什么时候除了内存池本身之外没有对它们的引用?我是否需要以某种方式为这些对象实现引用计数?

我已经在谷歌上搜索了几个小时,还没有看到一个内存池的实现不需要用户在使用完它后告诉内存池。我发现很难相信在C#中没有办法做到这一点。

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

有没有一种方法可以确保这些对象永远不会被收集,但知道什么时候除了内存池本身之外没有对它们的引用?

通常,对象池只包含对可用对象的引用(您可以在Roslyn中检查ObjectPool的实现)。考虑到这一点,您可以使用终结器来恢复对象,并在无法访问时将其返回到池中。

不过,我认为这不会提高性能。整个池将很快到达第2代,因此无法访问的对象将需要一个完整的垃圾收集才能返回到池中。根据程序中的内存使用模式,这种情况可能不会经常发生。当然可以使用GC.Collect()GC.WaitForPendingFinalizers(),但这也会影响性能。你可以试试看是否有用。

另一个问题是设计——您的对象与池耦合。

我宁愿尝试将对象显式地返回到池中。请记住,并非所有对象都必须返回。如果没有更多可用对象,则池可以创建新对象。那些没有归还的将被垃圾回收。检查是否有一些代码路径,您可以确定不再需要这些对象。如果找不到,请尝试重构代码。