13 c# reflection resources reference resourcemanager
我正在尝试为我正在写的小爱好游戏编写一个简单的资源管理器.此资源管理器需要执行的任务之一是卸载未使用的资源.我可以想到以两种方式做到这一点:
当一个对象不再需要对资源的引用时,它必须调用资源管理器的方法来表示它不再使用它; 要么
当一个对象不再需要对资源的引用时,它只是将其设置为null.然后,当要求资源管理器卸载未使用的资源时,它会获取每个资源的引用计数(通过反射?).如果引用计数为1(资源管理器将具有对资源的引用),则卸载资源.
有没有办法在C#中实现第二个解决方案?谢谢.
Eri*_*ert 31
几件事.首先,对象不参考计数; 参考计数方案具有循环参考问题,其中两个对象相互引用但是否则是不可访问的,从而泄漏..NET使用标记和扫描方法,不使用引用计数.
其次,虽然使用弱引用的建议并不可怕,但它也不是一个扣篮.您出于性能原因正在构建缓存.(我假设您对应用程序性能特征的仔细,经验,现实的研究已经令人信服地证明,为了获得可接受的性能,缓存策略是必要的;如果不是这样,那么您就是过早地做出这些决定.)缓存必须具有关于何时释放其资源的POLICY,否则它是内存泄漏.
您如何知道GC政策和您的政策是等效的政策?GC的设计并未考虑您的特定性能需求.也就是说,它旨在释放真正属于垃圾的资源,而不是为了达到您想到的任何特定性能目标.通过将决策委派给GC,您可以放弃根据性能需求调整缓存策略的能力.
Mar*_*ell 12
听起来你可以WeakReference从资源管理器中使用它.GC将完成剩下的工作.你需要做一点点投射,但它会很简单,并且会起作用.
class Manager {
Dictionary<string, WeakReference> refs =
new Dictionary<string, WeakReference>();
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)
}
Run Code Online (Sandbox Code Playgroud)