C# – 获取对象的引用数

我正在尝试为我正在写的小爱好游戏编写一个简单的资源管理器。 此资源管理器需要执行的任务之一是卸载未使用的资源。 我可以想到以两种方式做到这一点:

  • 当一个对象不再需要对资源的引用时,它必须调用资源管理器的方法来表示它不再使用它; 要么

  • 当一个对象不再需要对该资源的引用时,它只是将其设置为null。 然后,当要求资源管理器卸载未使用的资源时,它会获取每个资源的引用计数(通过reflection?)。 如果引用计数为1(资源管理器将具有对资源的引用),则卸载资源。

有没有办法在C#中实现第二个解决方案? 谢谢。

听起来你可以从资源管理器中使用WeakReference 。 GC将完成剩下的工作。 你需要做一点点投射,但它会很简单,并且会起作用。

 class Manager { Dictionary refs = new Dictionary(); public object this[string key] { get { WeakReference wr; if (refs.TryGetValue(key, out wr)) { if(wr.IsAlive) return wr.Target; refs.Remove(key); } return null; } set { refs[key] = new WeakReference(value); } } } static void Main() { Manager mgr = new Manager(); var obj = new byte[1024]; mgr["abc"] = obj; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); Console.WriteLine(mgr["abc"] != null); // true (still ref'd by "obj") obj = null; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); Console.WriteLine(mgr["abc"] != null); // false (no remaining refs) } 

几件事。 首先,对象不是引用计数; 参考计数方案具有循环参考问题,其中两个对象相互指代但是否则不可访问,从而泄漏。 .NET使用标记和扫描方法,不使用引用计数。

其次,虽然使用弱引用的建议并不可怕,但它也不是一个扣篮。 您出于性能原因构建缓存。 (我假设您对应用程序性能特征的仔细,经验,现实的研究已经令人信服地certificate,为了获得可接受的性能,缓存策略是必要的;如果不是这样,那么您就是过早地做出这些决定。)缓存必须具有关于何时释放其资源的POLICY,否则它是内存泄漏。

您如何知道GC政策和您的政策是等效的政策? GC的设计并未考虑您的特定性能需求。 也就是说,它旨在释放真正垃圾的资源,而不是实现您想到的任何特定性能目标。 通过将决策委派给GC,您可以放弃根据性能需求调整缓存策略的能力。

我们已经在.NET中有一个名为Garbage collector的资源管理器。 因此,一种非常有效的方法是将引用设置为null并且不执行任何操作。

更直接的答案:不,没有办法获得对象的引用。

您可能想要学习WeakReference类或使用缓存系统。

确保资源管理器将WeakReference用于您的资源。 这样,当没有其他人引用资源时,他们将有资格进行垃圾收集。

正如其他用户已经说过的那样,您尝试实现的function已经由GC完成,并且可以使用WeakReference进行微调。

这意味着在.NET,Java等托管环境中,这是一个非问题。

由于低级框架体系结构将您与内存管理隔离开来,如果您仍然需要这种function,我强烈建议您查看自己的代码体系结构,因为这意味着您在进行某种不良操作内存管理