我遇到的情况是我必须同时创建数千个对象,实例化对象和垃圾收集它们的成本会影响应用程序的性能,以及影响垃圾收集器运行会损害性能,因为这是在较旧的硬件上,所以我主要是试图阻止垃圾的创建。我相信内存池可以解决我的问题,但我不确定内存池如何知道池中的资源何时被释放以供重用。棘手的部分是来自池的对象接收器最终在整个程序中传递该对象,并且很难知道何时可以手动释放它。我希望它像g++ -L/my/dir/path/ -Wl,-rpath=/my/dir/path/ -l:foo.so -l:bar.so
,我可以知道什么时候没有人再使用它了。但我的理解是,如果我在内存池中使用WeakReference
,那么它最终会从池本身收集垃圾,我需要这些对象永远保留,以便它们继续被回收。有时程序可以在不需要对象的情况下运行一段时间,所以我想垃圾收集器会在下次需要它们之前收集它们,然后在另外数千个这样的对象产生时会触发另一个性能命中。
有没有办法可以确保永远不会收集这些对象,但是除了内存池本身之外什么时候没有引用它们?我是否需要以某种方式为这些对象实现引用计数?
我现在已经谷歌搜索了几个小时,并且没有看到没有实现内存池,也没有要求用户在内存池完成后知道内存池。我发现很难相信在C#中没有办法做到这一点。
答案 0 :(得分:1)
有没有办法可以确保永远不会收集这些对象,但是除了内存池本身之外什么时候没有对它们的引用?
通常,对象池只保存对可用对象的引用(您可以检查ObjectPool
implementation in Roslyn)。考虑到这一点,您可以使用终结器来恢复对象,并在无法访问时将其返回到池中。
但是,我认为它不会提高性能。整个池很快就会到达第2代,因此无法访问的对象需要将完整的垃圾收集返回到池中。根据程序中的内存使用模式,可能不会经常发生。您当然可以GC.Collect()
和GC.WaitForPendingFinalizers()
,但这也会影响性能。你可以试试看它是否有帮助。
另一个问题是设计 - 您的对象已耦合到池中。
我宁愿尝试将对象明确地返回池中。请记住,并非所有对象都必须返回。如果没有更多可用对象,则池可以创建新对象。没有返回的那些将被垃圾收集。检查是否有一些代码路径可以确定不再需要这些对象。如果找不到,请尝试重构代码。